2

I'm using this solution to sort an array of objects. This is the function:

function sortJsonArrayByProperty(objArray, prop, direction){
    if (arguments.length<2) throw new Error("sortJsonArrayByProp requires 2 arguments");
    var direct = arguments.length>2 ? arguments[2] : 1; //Default to ascending
    if (objArray && objArray.constructor===Array){
        var propPath = (prop.constructor===Array) ? prop : prop.split(".");
        objArray.sort(function(a,b){
            for (var p in propPath){
                if (a[propPath[p]] && b[propPath[p]]){
                    a = a[propPath[p]];
                    b = b[propPath[p]];
                }
            }
            // convert numeric strings to integers
            a = a.match(/^\d+$/) ? +a : a;
            b = b.match(/^\d+$/) ? +b : b;
            return ( (a < b) ? -1*direct : ((a > b) ? 1*direct : 0) );
        });
    }
}

It's a great solution.

But I have a problem with a column that store prices in this format:

950,75
1234,99
500,00

So, I have values with a comma separating decimals. Then, instead of this sequence:

222,55
550,00
2000,99
3000,00

I'm getting:

2000,99
222,55
3000,00
550,00

I'm trying to do some modification at this part:

a = a.match(/^\d+$/) ? +a : a; 
b = b.match(/^\d+$/) ? +b : b;

But that isn't working. What's wrong?

Community
  • 1
  • 1
  • There is no such thing as a "JSON object". JSON is a limited string serialization of JavaScript objects. – Touffy Oct 19 '15 at 15:19
  • What you're sorting isn't a JSON object. It's a JavaScript array, containing JavaScript objects. JSON is a *textual notation* for data exchange. If you're writing code, and you're not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Oct 19 '15 at 15:20
  • Why don't replacing commas `,` with decimal dots `.` and do it? – TaoPR Oct 19 '15 at 15:21

2 Answers2

1

In JavaScript, the decimal separator is always ., never , as it is in some locales. So to convert numeric strings that use , as a decimal to JavaScript numbers, you do this:

theNumber = +theString.replace(/\./g, '').replace(/,/g, '.');

or

theNumber = parseFloat(theString.replace(/\./g, '').replace(/,/g, '.'));

...depending on whether you want to ignore trailing invalid characters (+ doesn't, parseFloat does).

So that would suggest:

aVal = +a.replace(/\./g, '').replace(/,/g, '.');
bVal = +b.replace(/\./g, '').replace(/,/g, '.');
if (!isNaN(aVal) && !isNaN(bVal)) {
    a = aVal;
    b = bVal;
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

The comma is not recognized by JavaScript as part of a valid litteral number, so you cannot use unary + or any other built-in method to convert to a number. You need to replace commas with a period and then coerce to Number.

a = a.match(/^(\d+),(\d+)$/) ? +(a[1]+'.'+a[2]) : a; 
Touffy
  • 6,309
  • 22
  • 28