I have an object:
var Data = [{
item_id:1,
name:'John',
date:1262293200000,
votes:1
}, {
item_id:2,
name:'Nick',
date:1313784000000,
votes:2
},{
item_id:3,
name:'Paul',
date:1299186000000,
votes:-3
}]
I want to sort it by item_id, name, date and votes. Asc and desc. To do this I use this function:
function dynamicSort(property) {
return function (a,b) {
return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; }}
Array.prototype.sortBy = function(property) { return this.sort(dynamicSort(property)) }
Array.prototype.reverseBy = function(property) { return this.reverse(dynamicSort(property)) }
It's sorts and reverses nice, but only frow second calling. For example:
videoDataList.reverseBy("user_votes")
result will be wrong, but if I do sortBy and then again reverseBy it will be correct sorting.
Also if i call reverseBy and then sortBy sorting of sortBy will be correct.
Is it possible to fix?
3 Answers 3
There is no reverse function for an array accepting a function as a parameter.
You should try:
Array.prototype.reverseBy = function(property) {
return this.sortBy(dynamicSort(property)).reverse()
}
2 Comments
dynamicSort(property) is called once, its result (the sort function) is then passed as a parameter to Array.sort(). And that function (and only that function) is called for each comparison (btw. there are n * log(n) comparisons for sorting). So your optimization has no effect whatsoever.Array.reverse() doesn't take any parameters. It doesn't sort the array, merely reverses its current order. So you could either sort the list first (note that both Array.reverse() and Array.sort modify the array in-place, without creating a new array):
Array.prototype.reverseBy = function(property)
{
this.sortBy(property);
this.reverse();
return this;
};
Or you use a reverse sorting function:
function dynamicSortReverse(property)
{
var innerFunc = dynamicSort(property);
return function(a, b) { return -1 * innerFunc(a, b); };
}
Array.prototype.reverseBy = function(property) { return this.sort(dynamicSortReverse(property)); };
The second approach is the more efficient one.
Note that you can simplify your dynamicSort function if you are only sorting by numerical properties:
function dynamicSort(property)
{
return function (a, b)
{
return a[property] - b[property];
}
}
This should also be slightly more efficient. Of course, if you are sometimes sorting by string values you will still need the old function.