Sorting an Array in Javascript ["$85", "88 dollars", "$9.35", "$95", "96", "126", "5.95", "$36", "€124"]

StackOverflow https://stackoverflow.com/questions/23121437

質問

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!

役に立ちましたか?

解決

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!

他のヒント

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*)?/)) } );

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:

  1. Convert your array into some more usual form, e.g. numbers (for-loop and parse).
  2. Use standard Array.sort to sort your numbers.
  3. Transform the sorted Array of numbers back to previous format (you can store information about pairs String-Number before sorting and use it at the end).

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]);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top