Reputation: 1629
I've got a simple array that I'd like to reorder. This array could contain just numbers, or just words, or a combination like when describing currency. The following code works beautifully if it's either words or just numbers but doesn't order the currency the way a human would expect. It orders currency lexicographically ($100 is before $3), whereas I'd like to order it by number ignoring any other characters in the value.
howmuchdata = ["$85", "88 dollars", "$9.35", "$95", "96", "126", "5.95", "$36", "€124"];
howmuchdata = howmuchdata.sort();
howmuchdata = howmuchdata.sort(function(a,b){return a-b});
console.log(howmuchdata);
Is it just a matter of removing everything but the number, sorting based on the number left behind and adding whatever else was removed back in? Whatever is removed and put back may be different for each value too, so I can't just blanket take it out and put it back, it has to be done on a per value basis. I'd like the array returned as such:
howmuchdata = ["5.95", "$9.35", "$36", "$85", "88 dollars", "$95", "96", "€124", "126"];
Thanks very much for your help!
Upvotes: 0
Views: 939
Reputation: 288260
In those cases I use the following sort
function:
function sort(arr, f, isNum) {
var l = arr.length;
for(var i=0; i<l; ++i)
arr[i] = [f(arr[i]), arr[i]];
arr.sort(isNum
? function(a,b){ return a[0]-b[0]; }
: function(a,b){ return a[0]<b[0] ? -1 : a[0]>b[0] ? 1 : 0; }
);
for(var i=0; i<l; ++i)
arr[i] = arr[i][1];
return arr;
}
Use it like this:
sort(howmuchdata, function(i){ return i.match(/[\d.]+/)[0]; }, true);
/* or */
sort(howmuchdata, function(i){ return +i.match(/[\d.]+/)[0]; });
In ES6 it will be better:
sort(howmuchdata, i => +i.match(/[\d.]+/)[0]);
Upvotes: 0
Reputation: 2549
There are millions of ways how to define "order" on your Array of Strings. But there aren't millions of sort functions in Javascript.
I recommend to do it in 3 steps:
Upvotes: 0
Reputation: 22457
First off, you are sorting twice.
Second, sort
sorts your array in-place. You don't need to "assign" its result to another variable again.
Third: you want to sort numeric data; but you feed it strings. So you need to somehow convert the string data to numerics.
Try this (untested):
howmuchdata.sort(function(a,b){return Number(a.match(/\d+(\.\d*)?/)) - Number(b.match(/\d+(\.\d*)?/)) } );
Upvotes: 0
Reputation: 735
you can use RegEx in the sorting callback, just like that:
howmuchdata = ["$85", "88 dollars", "$9.35", "$95", "96", "126", "5.95", "$36", "€124"];
howmuchdata = howmuchdata.sort();
howmuchdata = howmuchdata.sort(function(a,b){
a = parseFloat(a.replace(/[^\d\.]/,''));
b = parseFloat(b.replace(/[^\d\.]/,''));
return a-b;
});
console.log(howmuchdata);
Good luck!
Upvotes: 1