PDA

View Full Version : grid stable sort


ericwaldheim
11-28-2006, 11:17 AM
drop-in replacement for DefaultDataModel sort:


YAHOO.ext.grid.DefaultDataModel.prototype.sort = function(sortInfo, columnIndex, direction, suppressEvent){
// store these so we can maintain sorting when we load new data
this.sortInfo = sortInfo;
this.sortColumn = columnIndex;
this.sortDir = direction;

var dsc = (direction && direction.toUpperCase() == 'DESC');
var sortType = null;
if(sortInfo != null){
if(typeof sortInfo == 'function'){
sortType = sortInfo;
}else if(typeof sortInfo == 'object'){
sortType = sortInfo.getSortType(columnIndex);;
}
}
var data = this.data;
var ds = [];
for (var i = 0; i < data.length; ++i)
ds.push([data[i][columnIndex], i]);

var fn = function(d1, d2){
var v1 = sortType ? sortType(d1[0], d1) : d1[0];
var v2 = sortType ? sortType(d2[0], d2) : d2[0];
if (v1 < v2) return dsc ? +1 : -1;
if (v1 > v2) return dsc ? -1 : +1;
if (d1[1] < d2[1]) return dsc ? +1 : -1;
return dsc ? -1 : +1;
};
ds.sort(fn);
var newData = [];
for (var i = 0; i < ds.length; ++i)
newData[i] = data[ds[i][1]];
this.data = newData;

if (!suppressEvent){
this.fireRowsSorted(columnIndex, direction);
}
}

jack.slocum
11-28-2006, 11:49 AM
What does it do differently?

jack.slocum
11-28-2006, 11:55 AM
Ah I just saw the title. Cool.

ericwaldheim
11-28-2006, 03:00 PM
This one is more efficient:

YAHOO.ext.grid.DefaultDataModel.prototype.sort = function(sortInfo, columnIndex, direction, suppressEvent){
// store these so we can maintain sorting when we load new data
this.sortInfo = sortInfo;
this.sortColumn = columnIndex;
this.sortDir = direction;

var dsc = (direction && direction.toUpperCase() == 'DESC');
var sortType = null;
if(sortInfo != null){
if(typeof sortInfo == 'function'){
sortType = sortInfo;
}else if(typeof sortInfo == 'object'){
sortType = sortInfo.getSortType(columnIndex);;
}
}
var data = this.data;
var ds = [];
for (var i = 0; i < data.length; ++i)
{
var row = data[i];
var value = row[columnIndex];
value = sortType ? sortType(value, row) : value;
ds.push([value, i]);
}

var fn = function(d1, d2){
if (d1[0] < d2[0]) return dsc ? +1 : -1;
if (d1[0] > d2[0]) return dsc ? -1 : +1;
if (d1[1] < d2[1]) return dsc ? +1 : -1;
return dsc ? -1 : +1;
};
ds.sort(fn);
var newData = [];
for (var i = 0; i < ds.length; ++i)
newData[i] = data[ds[i][1]];
this.data = newData;

if (!suppressEvent) {
this.fireRowsSorted(columnIndex, direction);
}
}

glassy
11-29-2006, 10:21 AM
Hmm... here's my version of this. I'm wondering which would be more efficient, or if mine is bad practice. It's just what came to my mind first. The changes from the original code are under the // comments


YAHOO.ext.grid.DefaultDataModel.prototype.sort = function(sortInfo, columnIndex, direction, suppressEvent){
this.sortInfo = sortInfo;
this.sortColumn = columnIndex;
this.sortDir = direction;

// we are going to preserve indexes, so save them first
for (i = 0; i < this.data.length; i++) {
this.data[i].index = i;
}

var dsc = (direction && direction.toUpperCase() == 'DESC');
var sortType = null;
if(sortInfo != null){
if(typeof sortInfo == 'function'){
sortType = sortInfo;
}else if(typeof sortInfo == 'object'){
sortType = sortInfo.getSortType(columnIndex);;
}
}
var fn = function(cells, cells2){
var v1 = sortType ? sortType(cells[columnIndex], cells) : cells[columnIndex];
var v2 = sortType ? sortType(cells2[columnIndex], cells2) : cells2[columnIndex];
if(v1 < v2)
return dsc ? +1 : -1;
if(v1 > v2)
return dsc ? -1 : +1;
// alright, their values are the same, so we use the index to compare
return cells.index - cells2.index;
};
this.data.sort(fn);
if(!suppressEvent){
this.fireRowsSorted(columnIndex, direction);
}
};

glassy
11-29-2006, 10:26 AM
Hmm.. the most efficient is probably caching the sortType? check like your last one, but maybe adding it to the data like I did so there is no need for the data assigning loop (if that's possible ... )