PDA

View Full Version : Useful Overrides - Additional Array methods



jsakalos
17 Apr 2008, 6:30 AM
I needed some additional methods for Array object and I haven't found them googling (better to say I found, bug they were GPL and I needed LGPL) so I've written them. Maybe also somebody else needs them....



// vim: ts=4:sw=4:nu:fdc=4:nospell
/**
* Ext.ux.Overrides
*
* This files contains various fixes and/or overridesds:
*
* @author Ing. Jozef Sakalos
* @version $Id: Ext.ux.Overrides.js 158 2008-04-10 00:03:18Z jozo $
* @date 13. March 2008
*
* @license Ext.ux.Overrides is licensed under the terms of
* the Open Source LGPL 3.0 license. Commercial use is permitted to the extent
* that the code/component(s) do NOT become part of another Open Source or Commercially
* licensed development library or toolkit without explicit permission.
*
* License details: http://www.gnu.org/licenses/lgpl.html
*/

/*global Ext */

// {{{
// conditional override
/**
* Same as Ext.override but overrides only if method doesn not exist in target class
*/
Ext.overrideIf = function(origclass, overrides) {
if(overrides) {
var p = origclass.prototype;
for(var method in overrides) {
if(!p[method]) {
p[method] = overrides[method];
}
}
}
};
// }}}
// {{{
// methods for Array object
Ext.overrideIf(Array, {

// {{{
/**
* One dimensional copy
* @return {Array} New array that is copy of this
*/
copy:function() {
var a = [];
for(var i = 0, l = this.length; i < l; i++) {
a.push(this[i]);
}
return a;
} // eo function copy
// }}}
// {{{
/**
* @return {Integer} index of v or -1 if not found
* @param {Mixed} v Value to find indexOf
* @param {Integer} b Starting index
*/
,indexOf:function(v, b) {
for(var i = +b || 0, l = this.length; i < l; i++) {
if(this[i] === v) {
return i;
}
}
return -1;
} // eo function indexOf
// }}}
// {{{
/**
* @return {Array} intersection of this and passed arguments
*/
,intersect:function() {
if(!arguments.length) {
return [];
}
var a1 = this, a2, a;
for(var k = 0, ac = arguments.length; k < ac; k++) {
a = [];
a2 = arguments[k] || [];
for(var i = 0, l = a1.length; i < l; i++) {
if(-1 < a2.indexOf(a1[i])) {
a.push(a1[i]);
}
}
a1 = a;
}
return a.unique();
} // eo function intesect
// }}}
// {{{
/**
* @return {Integer} index of v or -1 if not found
* @param {Mixed} v Value to find indexOf
* @param {Integer} b Starting index
*/
,lastIndexOf:function(v, b) {
b = +b || 0;
var i = this.length;
while(i-- > b) {
if(this[i] === v) {
return i;
}
}
return -1;
} // eof function lastIndexOf
// }}}
// {{{
/**
* @return {Array} New array that is union of this and passed arguments
*/
,union:function() {
var a = this.copy(), a1;
for(var k = 0, ac = arguments.length; k < ac; k++) {
a1 = arguments[k] || [];
for(var i = 0, l = a1.length; i < l; i++) {
a.push(a1[i]);
}
}
return a.unique();
} // eo function union
// }}}
// {{{
/**
* Removes duplicates from array
* @return {Array} new array with duplicates removed
*/
,unique:function() {
var a = [], i, l = this.length;
for(i = 0; i < l; i++) {
if(a.indexOf(this[i]) < 0) {
a.push(this[i]);
}
}
return a;
} // eo function unique
// }}}

});
// }}}

// eof

galdaka
17 Apr 2008, 10:40 AM
Is posible add this functions? :)



/*POR DEFECTO
Array.Prototype.toString();
Array.Prototype.toLocaleString();
Array.Prototype.concat();
Array.Prototype.join();
Array.Prototype.pop();
Array.Prototype.push();
Array.Prototype.reverse();
Array.Prototype.shift();
Array.Prototype.slice();
Array.Orototype.sort();
Array.Prototype.splice();
Array.Prototype.unshift();
*/
/*Redefinimos algunas funciones por si no existen en el interprete javaScript del navegador*/
// Array.concat() - Join two arrays
if (typeof Array.prototype.concat === 'undefined') {
Array.prototype.concat = function(a) {
for (var i = 0, b = this.copy(); i < a.length; i++) {
b[b.length] = a[i];
}
return b;
};
}
// Array.copy() - Copy an array
if (typeof Array.prototype.copy === 'undefined') {
Array.prototype.copy = function() {
var a = [],
i = this.length;
while (i--) {
a[i] = typeof this[i].copy !== 'undefined' ? this[i].copy() : this[i];
}
return a;
};
}
// Array.pop() - Remove and return the last element of an array
if (typeof Array.prototype.pop === 'undefined') {
Array.prototype.pop = function() {
var b = this[this.length - 1];
this.length--;
return b;
};
}
// Array.push() - Add an element to the end of an array, return the new length
if (typeof Array.prototype.push === 'undefined') {
Array.prototype.push = function() {
for (var i = 0, b = this.length, a = arguments, l = a.length; i < l; i++) {
this[b + i] = a[i];
}
return this.length;
};
}
// Array.shift() - Remove and return the first element
if (typeof Array.prototype.shift === 'undefined') {
Array.prototype.shift = function() {
for (var i = 0, b = this[0], l = this.length - 1; i < l; i++) {
this[i] = this[i + 1];
}
this.length--;
return b;
};
}
// Array.slice() - Copy and return several elements
if (typeof Array.prototype.slice === 'undefined') {
Array.prototype.slice = function(a, c) {
var i, l = this.length,
r = [];
if (!c) {
c = l;
}
if (c < 0) {
c = l + c;
}
if (a < 0) {
a = l - a;
}
if (c < a) {
i = a;
a = c;
c = i;
}
for (i = 0; i < c - a; i++) {
r[i] = this[a + i];
}
return r;
};
}
// Array.splice() - Remove or replace several elements and return any deleted elements
if (typeof Array.prototype.splice === 'undefined') {
Array.prototype.splice = function(a, c) {
var i = 0,
e = arguments,
d = this.copy(),
f = a,
l = this.length;
if (!c) {
c = l - a;
}
for (i; i < e.length - 2; i++) {
this[a + i] = e[i + 2];
}
for (a; a < l - c; a++) {
this[a + e.length - 2] = d[a - c];
}
this.length -= c - e.length + 2;
return d.slice(f, f + c);
};
}
// Array.unshift() - Add an element to the beginning of an array
if (typeof Array.prototype.unshift === 'undefined') {
Array.prototype.unshift = function() {
this.reverse();
var a = arguments,
i = a.length;
while (i--) {
this.push(a[i]);
}
this.reverse();
return this.length;
};
}
/*EXTRA
Array.Prototype.contains
Array.Prototype.equals
Array.Prototype.indexOf
Array.Prototype.getLast
Array.Prototype.filter
Array.Prototype.map
Array.Prototype.pushAtIndex
Array.Prototype.removeByIndex
Array.Prototype.removeByValue
Array.Prototype.copy
Array.Prototype.swap
Array.Prototype.shuffle
Array.Prototype.search
Array.Prototype.union
Array.Prototype.subtract
Array.Prototype.intersect
Array.Prototype.removeDuplicates
Array.Prototype.exclusion
Array.Prototype.unsortedUnion
Array.Prototype.unsortedSubtract
Array.Prototype.unsortedIntersect
Array.Prototype.unsortedRemoveDuplicates
Array.Prototype.unsortedExclusion
Array.Prototype.quickSort
Array.Prototype.forEach
Array.Prototype.indexOf
Array.Prototype.insert
Array.Prototype.lastIndexOf
Array.Prototype.random
Array.Prototype.shuffle
Array.Prototype.unique
Array.Prototype.walk
*/
//True si contiene el string que se le pasa como parametro y False en caso contrario.
Array.prototype.contains = function(s) {
for (var i = 0; i < this.length; ++i) {
if (this[i] === s) {
return true;
}
}
return false;
};
//True si los 2 Arrays son iguales y false en caso contrario
Array.prototype.equals = function(a) {
if (this.length != a.length) {
return false;
}
for (var i = 0; i < this.length; ++i) {
if (this[i] !== a[i]) {
return false;
}
}
return true;
};
//El indice del primer elemento del array que se correpsonda con el que le pasas como parametro. -1 si no encuentra nada.
Array.prototype.indexOf = function(item) {
for (var i = 0; i < this.length; ++i) {
if (this[i] === item) {
return i;
}
}
return - 1;
};
//Devuelve el ultimo elemento del array
Array.prototype.getLast = function() {
return this[this.length - 1];
};
//Elimina los elementos del array que devuelvan 'false' en la funci

jsakalos
17 Apr 2008, 10:55 AM
Perfect! It's a lot more. Are they LGPL?

I'm not going to take them all but it's good "repository" of methods that I'll use as needed.

galdaka
17 Apr 2008, 1:40 PM
Yes you can use theses files free for create Ext overrides and share ;)

Greetings,

Hacker-CB
21 Feb 2010, 6:11 AM
Has somebody use this overrides?
Is it safe in Ext 3.1.1?

jsakalos
21 Feb 2010, 8:22 AM
Me not. @galdaka, have you tested them against Ext 3.1.1?

ratbeard
6 Mar 2010, 2:28 PM
In general I'd advise against this, especially if your code is to be used as a library. Its nowhere near as dangerous as extending Object.prototype, but I've run in to strange issues when extending core types like Array in some more exotic environments, like rhino inside couchdb. Of more relevance to most is that it makes the debugging output in firebug and friends much noisier.

You might like underscore instead. It adds a nice collection of helper methods on to `_`, and delegates to the native version if available. Also nice is that it lets you iterate over objects and array with the same api:

http://documentcloud.github.com/underscore/

It bugs me that Ext adds `remove` to Array.prototype. It seems like you either don't want to add anything, or go all the way like Prototype and add lots of functionality on. Don't know why they just didn't add this one method as Ext.remove, or something.

jsakalos
6 Mar 2010, 5:26 PM
Is the above a theory or your personal liking or do the overrides cause real troubles? BTW, I use the overrides from the first post in a huge Ext 2.3 based application w/o any side effects.

ratbeard
7 Mar 2010, 8:45 AM
It has caused me problems in rhino in serverside javascript as I said, though I realize that's not a common use case. It does make looking at console output worse as now every Array (or function) has a little drop down with the methods you've added on. You should be fine adding the extension methods in for your project, but I'd think twice if building a library for others to use, as not everyone wants core objects to be extended. I found this thread because I was trying to google why Ext adds the single `remove` method on Array.

ratbeard
7 Mar 2010, 11:25 AM
Though thinking about it, it should be much safer to extend types to fill in missing implementations (like indexOf, map), than to add on your own new methods, since chances are if you load someone else's code that does it too it will have the same API.