我想做这样的事情:
var data = [
{
sortData: {a: 'a', b: 2}
},
{
sortData: {a: 'a', b: 1}
},
{
sortData: {a: 'b', b: 5}
},
{
sortData: {a: 'a', b: 3}
}
];
data = _.sortBy(data, ["sortData.a", "sortData.b"]);
_.map(data, function(element) {console.log(element.sortData.a + " " + element.sortData.b);});
并输出此信息:
"a 1"
"a 2"
"a 3"
"b 5"
不幸的是,这不起作用,数组仍以其原始形式排序。 This would work if the fields weren't nested inside the sortData
.如何使用lodash / underscore按多个嵌套字段对对象数组进行排序?
我已将此转换为lodash功能请求:https://github.com/lodash/lodash/issues/581
答案 0 :(得分:36)
更新:请参阅下面的评论,在大多数情况下,这不是一个好的解决方案。
有人回答in the issue I created。这是他的答案,内联:
_.sortBy(data, function(item) {
return [item.sortData.a, item.sortData.b];
});
我没有意识到你被允许从该函数返回一个数组。文档没有提到这一点。
答案 1 :(得分:19)
如果您需要指定排序方向,可以将_.orderBy
与 Lodash 4.x 中的函数数组语法一起使用:
_.orderBy(data, [
function (item) { return item.sortData.a; },
function (item) { return item.sortData.b; }
], ["asc", "desc"]);
这将首先按属性a
升序排序,对于属性a
具有相同值的对象,将按属性b
降序排序。
当a
和b
属性具有不同类型时,它会按预期工作。
以下是使用此语法的jsbin example。
答案 2 :(得分:17)
lodash版本3中有_.sortByAll
方法:
https://github.com/lodash/lodash/blob/3.10.1/doc/README.md#_sortbyallcollection-iteratees
Lodash第4版,已统一:
https://lodash.com/docs#sortBy
其他选择是自己对值进行排序:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
function compareValues(v1, v2) {
return (v1 > v2)
? 1
: (v1 < v2 ? -1 : 0);
};
var data = [
{ a: 2, b: 1 },
{ a: 2, b: 2 },
{ a: 1, b: 3 }
];
data.sort(function (x, y) {
var result = compareValues(x.a, y.a);
return result === 0
? compareValues(x.b, y.b)
: result;
});
// data after sort:
// [
// { a: 1, b: 3 },
// { a: 2, b: 1 },
// { a: 2, b: 2 }
// ];
答案 3 :(得分:10)
真棒,简单的方法是:
_.sortBy(data, [function(item) {
return item.sortData.a;
}, function(item) {
return item.sortData.b;
}]);
我从检查lodash的源代码中找到它,它总是逐个检查函数。
希望有所帮助。
答案 4 :(得分:6)
使用ES6 easy语法和lodash
sortBy(item.sortData, (item) => (-item.a), (item) => (-item.b))
答案 5 :(得分:0)
我认为这在大多数情况下可以使用下划线:
var properties = ["sortData.a", "sortData.b"];
data = _.sortBy(data, function (d) {
var predicate = '';
for (var i = 0; i < properties.length; i++)
{
predicate += (i == properties.length - 1
? 'd.' + properties[i]
: 'd.' + properties[i] + ' + ')
}
return eval(predicate)
});
答案 6 :(得分:0)
如果问题是整数转换为字符串,则在整数之前添加零,使其长度与集合中最长的相同:
var maxLength = _.reduce(data, function(result, item) {
var bString = _.toString(item.sortData.b);
return result > bString.length ? result : bString.length;
}, 0);
_.sortBy(data, function(item) {
var bString = _.toString(item.sortData.b);
if(maxLength > bString.length) {
bString = [new Array(maxLength - bString.length + 1).join('0'), bString].join('');
}
return [item.sortData.a, bString];
});