How can one compare string and numeric values (respecting negative values, with null always last)?

前端 未结 4 949
南方客
南方客 2021-01-05 00:03

I\'m trying to sort an array of values that can be a mixture of numeric or string values (e.g. [10,\"20\",null,\"1\",\"bar\",\"-2\",-3,null,5,\"foo\"]). How can

相关标签:
4条回答
  • 2021-01-05 00:37

    Use this:

    function typeOrder(x) {
        if (x == null)
            return 2;
        if (isNaN(+x))
            return 1;
        return 0;
    }
    function sortNumber(a, b) {
        a = parseInt(a, 10); b = parseInt(b, 10);
        if (isNaN(a) || isNaN(b))
            return 0;
        return a - b;
    }
    function sortString(a, b) {
        if (typeof a != "string" || typeof b != "string")
           return 0;
        return +(a > b) || -(b > a);
    }
    
    order = order == "dsc" ? -1 : 1;
    numericArr.sort(function(a, b) {
        return order * ( typeOrder(a)-typeOrder(b)
                         || sortNumber(a, b)
                         || sortString(a, b)
                       );
    });
    

    (updated fiddle)

    0 讨论(0)
  • 2021-01-05 00:39
    function sortByDataString(a, b) {
        if (a === null) {
            return 1;
        }
        if (b === null) {
            return -1;
        }
        if (isNumber(a) && isNumber(b)) {
            if (parseInt(a,10) === parseInt(b,10)) {
                return 0;
            }
            return parseInt(a,10) > parseInt(b,10) ? 1 : -1;
        }
        if (isNumber(a)) {
            return -1;
        }
        if (isNumber(b)) {
            return 1;
        }
        if (a === b) {
            return 0;
        }
        return a > b ? 1 : -1;
    }
    

    fiddle here: http://jsfiddle.net/gxFGN/6/

    I left out the order parameter, but you could always reverse the array at the end if needed.

    0 讨论(0)
  • 2021-01-05 00:41

    I'm pretty sure that your problem is a red herring... the abstract function that you past into sort doesn't get a third parameter (in your case _order). So in your situation that's always going to be undefined.

    Please reconsider your code with that in mind and see what you get.

    The array you specify is entirely Numeric so your sort should work correctly, though as other commenters have suggested, if your array ever winds up with string values (i.e. "10", "-7" etc) you'll want to parseInt and test for isNaN before doing your comparison.

    0 讨论(0)
  • 2021-01-05 00:56

    You should first check to see if either value is null and return the opposite value.


    On a side note:

    For your default _order value, you should check if the parameter is undefined instead of comparing its value to null. If you try to compare something that is undefined directly you will get a reference error:

    (undefinedVar == null) // ReferenceError: undefinedVar is not defined
    

    Instead, you should check if the variable is undefined:

    (typeof undefinedVar == "undefined") // true
    

    Also, it's probably a better idea to wrap your compare function in a closure instead of relying on a global order variable.

    Sometime like:

    [].sort(function(a, b){ return sort(a, b, order)})
    

    This way you can sort at a per-instance level.


    http://jsfiddle.net/gxFGN/10/

    JavaScript

    function sort(a, b, asc) {
        var result;
    
        /* Default ascending order */
        if (typeof asc == "undefined") asc = true;
    
        if (a === null) return 1;
        if (b === null) return -1;
        if (a === null && b === null) return 0;
    
        result = a - b;
    
        if (isNaN(result)) {
            return (asc) ? a.toString().localeCompare(b) : b.toString().localeCompare(a);
        }
        else {
            return (asc) ? result : -result;
        }
    }
    
    0 讨论(0)
提交回复
热议问题