PDA

View Full Version : sorting objects



DaveC426913
27 Oct 2010, 10:15 AM
I've got a list with several objects, each having an id and html:

myList.add({id:"i1",html:"foo"});
myList.add({id:"i2",html:"bar"});

Now I want to sort them. If they were just an 1D array, I could sort them with myList.sort();
But they're complex objects. If they were "merely" 2D arrays, I could do something like sort on myList[0].

Is there a way to sort objects? I've been looking in the API but nothing found. Seems like it's going to be a laborious and processor-intensive algorithm to pull out the indices, sort them separately, then reload the objects by id into a new array.


(Step 2: Once I get them sorted by one index, I'll want to be able to sort by any 'column').
(Step 3: My list items will grow in complexity, having multiple properties and subcomponents).

evant
27 Oct 2010, 3:29 PM
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort

DaveC426913
28 Oct 2010, 5:42 AM
...but (as I mentioned in my post) this isn't going to work on an array of objects...

Kask
28 Oct 2010, 5:59 AM
evants link says it all ...

You have to pass in a function tho that handles the comparisson of the objects ...



myList.add({id:"i1",html:"foo"});
myList.add({id:"i2",html:"bar"});

myList.sort(function(item1, item2) {
if(item1.id == item2.id) return 0;
return (item1.id < item2.id) ? -1 : 1;
});

evant
28 Oct 2010, 6:12 AM
Yes you can, it says it right there on the page.



var arr = [{x: 3}, {x: 5}, {x: 1}, {x: 7}, {x: 19}, {x: 2}];

arr.sort(function(a, b){
a = a.x;
b = b.x;
if(a < b) {
return -1;
} else if (a > b) {
return 1;
}
return 0;
});

Ext.each(arr, function(o){
console.log(o.x);
});

DaveC426913
28 Oct 2010, 6:17 AM
Yes you can, it says it right there on the page.

Well, I did read over the page, but I still see nothing that applies to objects or implies that objects can be used directly.

However, between you and Kask, I have the solution to how I can use array.sort() upon an array of objects.

Thanks.

evant
28 Oct 2010, 6:40 AM
The fact that you can pass in a custom comparator function indicates you can sort on any criteria you wish, it's a fairly common pattern.

DaveC426913
29 Oct 2010, 7:33 AM
OK, the sort is actually working fine, it's the objects that have gone splah.



sort: function(){
textPanel = Ext.getCmp("myList_textpanel");
console.log("unsorted:")
Ext.each(textPanel.items.items,function(o){console.log(o)})
textPanel.items.items.sort(function(a, b){
a = a.id;
b = b.id;
if(a < b) {
console.log(a+"<"+b);
return -1;
} else if (a > b) {
console.log(a+">"+b);
return 1;
}
return 0;
});
arrItems = new Array();
arrItems = textPanel.items.items;
this.clearAll();
Ext.each(arrItems,function(o){this.addItems([o.id,o.html])});
textPanel.doLayout();
console.log("sorted:")
Ext.each(textPanel.items.items,function(o){console.log(o)})
}

I can't seem to sort the textPanel objects directly, so I have to move them to an array and sort them there. But I don't have a function for adding an object to the list, only for adding a name/value array:



addItems: function(arrItems){
//array of arrays of id,html
textPanel = Ext.getCmp("myList_textpanel");
Ext.each(arrItems, function(o){ textPanel.add({id:o[0],html:o[1]}); })
textPanel.doLayout();
},


I don't know what to do.

Try to sort the list directly, and then somehow refresh it?

Or pull the list into some array, sort it, then add each iotem back into the list.

DaveC426913
29 Oct 2010, 10:32 AM
Sorry, I'm beat. I've tried everything I can think of.

I tried method 1 (above) - clone the object array (I used this code (http://my.opera.com/GreyWyvern/blog/show.dml/1725165) see below):

This calls the clone function 50368 times, then dies before returning anything.

I give up.



sort: function(){
Object.prototype.clone = function() {
console.log("!");
var newObj = (this instanceof Array) ? [] : {};
for (i in this) {
if (i == 'clone') continue;
if (this[i] && typeof this[i] == "object") {
newObj[i] = this[i].clone();
}
else {
newObj[i] = this[i]
}
}
return newObj;
};

textPanel = Ext.getCmp("myList_textpanel");
console.log("unsorted:");
console.log(textPanel.items);
var arr = textPanel.clone();
arr.sort(function(a, b){
a = a.id;
b = b.id;
if(a < b) {
console.log(a+"<"+b);
return -1;
} else if (a > b) {
console.log(a+">"+b);
return 1;
}
return 0;
});
Ext.each(arr,function(o){textPanel.items.add(o)})
console.log("sorted:");
console.log(textPanel.items);
}