从这个最初的问题,我将如何在多个字段应用排序?

使用这种稍作调整的结构,我将如何排序城市(上升)和价格(下降)?

var homes = [
    {"h_id":"3",
     "city":"Dallas",
     "state":"TX",
     "zip":"75201",
     "price":"162500"},
    {"h_id":"4",
     "city":"Bevery Hills",
     "state":"CA",
     "zip":"90210",
     "price":"319250"},
    {"h_id":"6",
     "city":"Dallas",
     "state":"TX",
     "zip":"75000",
     "price":"556699"},
    {"h_id":"5",
     "city":"New York",
     "state":"NY",
     "zip":"00010",
     "price":"962500"}
    ];

我喜欢的事实是,给出的答案提供了一个一般的方法。在我计划使用这段代码的地方,我将不得不对日期以及其他东西进行排序。“启动”对象的能力似乎很方便,如果不是有点麻烦的话。

我试图把这个答案构建成一个很好的通用示例,但我运气不太好。


当前回答

您可以使用链式排序方法,取值的增量,直到它达到不等于零的值。

var data = [{ h_id: "3", city: "Dallas", state: "TX", zip: "75201", price: "162500" }, { h_id: "4", city: "Bevery Hills", state: "CA", zip: "90210", price: "319250" }, { h_id: "6", city: "Dallas", state: "TX", zip: "75000", price: "556699" }, { h_id: "5", city: "New York", state: "NY", zip: "00010", price: "962500" }]; data.sort(function (a, b) { return a.city.localeCompare(b.city) || b.price - a.price; }); console.log(data); .as-console-wrapper { max-height: 100% !important; top: 0; }

或者,使用es6,简单地:

data.sort((a, b) => a.city.localeCompare(b.city) || b.price - a.price);

其他回答

我认为这可能是最简单的方法。

https://coderwall.com/p/ebqhca/javascript-sort-by-two-fields

这真的很简单,我尝试了3个不同的键值对,它工作得很好。

这是一个简单的例子,查看链接了解更多细节

testSort(data) {
    return data.sort(
        a['nameOne'] > b['nameOne'] ? 1
        : b['nameOne'] > a['nameOne'] ? -1 : 0 ||
        a['date'] > b['date'] ||
        a['number'] - b['number']
    );
}

我喜欢snowburn的方法,但它需要调整来测试城市的等效性,而不是差异。

homes.sort(
   function(a,b){
      if (a.city==b.city){
         return (b.price-a.price);
      } else {
         return (a.city-b.city);
      }
   });

以下是@ snowburn的解决方案的通用版本:

var sortarray = [{field:'city', direction:'asc'}, {field:'price', direction:'desc'}];
array.sort(function(a,b){
    for(var i=0; i<sortarray.length; i++){
        retval = a[sortarray[i].field] < b[sortarray[i].field] ? -1 : a[sortarray[i].field] > b[sortarray[i].field] ? 1 : 0;
        if (sortarray[i].direction == "desc") {
            retval = retval * -1;
        }
        if (retval !== 0) {
            return retval;
        }
    }
}


})

这是基于我正在使用的排序例程。我没有测试这个特定的代码,所以它可能有错误,但你知道的。其思想是基于第一个表示差异的字段进行排序,然后停止并转到下一个记录。因此,如果您按三个字段排序,并且compare中的第一个字段足以确定正在排序的两个记录的排序顺序,那么将返回该排序结果并转到下一个记录。

我在5000条记录上测试了它(实际上使用了更复杂的排序逻辑),它在眨眼之间就做到了。如果实际向客户端加载超过1000条记录,则可能应该使用服务器端排序和过滤。

这段代码不区分大小写,我把它留给读者来处理这个微不足道的修改。

简单的一个:

var someArray = [...];

function generateSortFn(props) {
    return function (a, b) {
        for (var i = 0; i < props.length; i++) {
            var prop = props[i];
            var name = prop.name;
            var reverse = prop.reverse;
            if (a[name] < b[name])
                return reverse ? 1 : -1;
            if (a[name] > b[name])
                return reverse ? -1 : 1;
        }
        return 0;
    };
};

someArray.sort(generateSortFn([{name: 'prop1', reverse: true}, {name: 'prop2'}]));

改编自@chriskelly的回答。


大多数答案都忽略了,如果价值在1万美元以下或超过100万美元,价格将无法正确排序。原因是JS按字母顺序排序。这里回答得很好,为什么JavaScript不能对“5,10,1”排序,这里如何正确地对整数数组排序。

最后,如果我们要排序的字段或节点是一个数字,我们必须做一些计算。我并不是说在这种情况下使用parseInt()是正确的答案,排序结果更重要。

var homes = [{ "h_id": "2", "city": "Dallas", "state": "TX", "zip": "75201", "price": "62500" }, { "h_id": "1", "city": "Dallas", "state": "TX", "zip": "75201", "price": "62510" }, { "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": "319250" }, { "h_id": "6", "city": "Dallas", "state": "TX", "zip": "75000", "price": "556699" }, { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" }]; homes.sort(fieldSorter(['price'])); // homes.sort(fieldSorter(['zip', '-state', 'price'])); // alternative function fieldSorter(fields) { return function(a, b) { return fields .map(function(o) { var dir = 1; if (o[0] === '-') { dir = -1; o = o.substring(1); } if (!parseInt(a[o]) && !parseInt(b[o])) { if (a[o] > b[o]) return dir; if (a[o] < b[o]) return -(dir); return 0; } else { return dir > 0 ? a[o] - b[o] : b[o] - a[o]; } }) .reduce(function firstNonZeroValue(p, n) { return p ? p : n; }, 0); }; } document.getElementById("output").innerHTML = '<pre>' + JSON.stringify(homes, null, '\t') + '</pre>'; <div id="output"> </div>


用来测试的小提琴