Сортировка элементов в массиве более чем одним полем с lodash
Как я могу отсортировать массив объектов более чем одним полем с помощью lodash. Итак, для такого массива:
[
{a: 'a', b: 2},
{a: 'a', b: 1},
{a: 'b', b: 5},
{a: 'a', b: 3},
]
Я бы ожидал этого результата
[
{a: 'a', b: 1},
{a: 'a', b: 2},
{a: 'a', b: 3},
{a: 'b', b: 5},
]
Ответы
Ответ 1
Это намного проще в текущей версии lodash (2.4.1). Вы можете просто сделать это:
var data = [
{a: 'a', b: 2},
{a: 'a', b: 1},
{a: 'b', b: 5},
{a: 'a', b: 3},
];
data = _.sortBy(data, ["a", "b"]); //key point: Passing in an array of key names
_.map(data, function(element) {console.log(element.a + " " + element.b);});
И он выведет это на консоль:
"a 1"
"a 2"
"a 3"
"b 5"
Предупреждение: см. комментарии ниже. Похоже, это было кратко названо sortByAll
в версии 3, но теперь оно вернется к sortBy
.
Ответ 2
Почему бы вам не использовать чистый javascript?
var foo = [
{a: 'a', b: 2},
{a: 'a', b: 1},
{a: 'b', b: 5},
{a: 'a', b: 3},
];
foo.sort (function (a,b) {
return 2 * (a.a > b.a ? 1 : a.a < b.a ? -1 : 0) + 1 * (a.b > b.b ? 1 : a.b < b.b ? -1 : 0)
})
/*
[
{a: 'a', b: 1},
{a: 'a', b: 2},
{a: 'a', b: 3},
{a: 'b', b: 5},
]
*/
Обновление: Heres более общий подход
function fieldSort (arr, fields) {
return arr.slice().sort ( function (a,b) {
return fields.reduce ( function (c,d,e,f) {
var _a = a[d]||0,_b = b[d]||0
return c + (f.length - e) * (_a>_b?1:_a<_b?-1:0)
},0)
})
}
fieldSort (foo,["a","b"])
Обновление 2:
Если вы хотите поддерживать цепочку, вы можете добавить этот метод к прототипу loadash
_.prototype["fieldSort"] = (function (_) {
function wrap (val,chain) {
this.__wrapped__ = val;
this.__chain__ = !!chain;
}
wrap.prototype = _.prototype
function fieldSort(fields) {
return this.slice().sort(function (a, b) {
return fields.reduce(function (c, d, e, f) {
var _a = a[d] || 0,
_b = b[d] || 0
return c + (f.length - e) * (_a > _b ? 1 : _a < _b ? -1 : 0)
},0)
})
}
return function () {
return new wrap (fieldSort.apply (this.__wrapped__,arguments),!!this.__chain__);
};
})(_)
_(foo).fieldSort (["a","b"]);
Heres a Fiddle
Изменить примечания:
Спасибо @AndreasKöberle за рассказ о необязательном параметре reduce