Underscore.js sort an array of objects alphanumerically

后端 未结 3 1159
耶瑟儿~
耶瑟儿~ 2021-01-16 18:49

I have an array of objects and I\'m trying to sort them alphanumerically, take the following example:

var objs = {
    \'obj1\': {\'name\': \'Object21\'},
           


        
3条回答
  •  清酒与你
    2021-01-16 19:32

    I've managed to find a solution to this myself using Google :-) here's what I used for those that need this in future and it's actually called "Natural Sorting"

    use by calling _.sortByNat(objs, function(obj) { return obj.name; })

    /*
    * Backbone.js & Underscore.js Natural Sorting
    *
    * @author Kevin Jantzer 
    * @since 2013-10-17
    * 
    * NOTE: make sure to include the Natural Sort algorithm by Jim Palmer (https://github.com/overset/javascript-natural-sort)
    */
    
    // add _.sortByNat() method
    _.mixin({
    
        sortByNat: function(obj, value, context) {
            var iterator = _.isFunction(value) ? value : function(obj){ return obj[value]; };
            return _.pluck(_.map(obj, function(value, index, list) {
              return {
                value: value,
                index: index,
                criteria: iterator.call(context, value, index, list)
              };
            }).sort(function(left, right) {
              var a = left.criteria;
              var b = right.criteria;
              return naturalSort(a, b);
            }), 'value');
        }
    });
    
    /*
    * Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license
    * Author: Jim Palmer (based on chunking idea from Dave Koelle)
    * https://github.com/overset/javascript-natural-sort
    */
    function naturalSort (a, b) {
        var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,
            sre = /(^[ ]*|[ ]*$)/g,
            dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
            hre = /^0x[0-9a-f]+$/i,
            ore = /^0/,
            i = function(s) { return naturalSort.insensitive && (''+s).toLowerCase() || ''+s },
            // convert all to strings strip whitespace
            x = i(a).replace(sre, '') || '',
            y = i(b).replace(sre, '') || '',
            // chunk/tokenize
            xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
            yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
            // numeric, hex or date detection
            xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),
            yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null,
            oFxNcL, oFyNcL;
        // first try and sort Hex codes or Dates
        if (yD)
            if ( xD < yD ) return -1;
            else if ( xD > yD ) return 1;
        // natural sorting through split numeric strings and default strings
        for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
            // find floats not starting with '0', string or 0 if not defined (Clint Priest)
            oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
            oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
            // handle numeric vs string comparison - number < string - (Kyle Adams)
            if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { return (isNaN(oFxNcL)) ? 1 : -1; }
            // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
            else if (typeof oFxNcL !== typeof oFyNcL) {
                oFxNcL += '';
                oFyNcL += '';
            }
            if (oFxNcL < oFyNcL) return -1;
            if (oFxNcL > oFyNcL) return 1;
        }
        return 0;
    }
    
    // extend Array to have a natural sort
    Array.prototype.sortNat = function(){
        return Array.prototype.sort.call(this, naturalSort)
    }
    

提交回复
热议问题