如何使用lodash/underscore按多个嵌套字段排序?

Dan*_*lan 28 javascript underscore.js lodash

我想做这样的事情:

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);});
Run Code Online (Sandbox Code Playgroud)

并输出这个:

"a 1"
"a 2"
"a 3"
"b 5"
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用,数组仍以原始形式排序. 如果字段没有嵌套在内部,这将起作用sortData. 如何使用lodash/underscore按多个嵌套字段对对象数组进行排序?

我把它变成了一个lodash功能请求:https://github.com/lodash/lodash/issues/581

Dan*_*lan 39

更新:请参阅下面的评论,在大多数情况下,这不是一个好的解决方案.


在我创建的问题中有人回答.这是他的回答,内联:

_.sortBy(data, function(item) {
   return [item.sortData.a, item.sortData.b];
});
Run Code Online (Sandbox Code Playgroud)

我没有意识到你被允许从该函数返回一个数组.文档没有提到这一点.

  • 这是因为当你返回一个数组时,它会被转换为字符串,然后进行比较,但如果你的第二个项目是数字,并且你想要按第二个值排序为数字,那么它将无法工作. (13认同)

ken*_*iru 20

如果需要指定排序方向,可以使用Lodash 4.x中_.orderBy的函数数组语法:

_.orderBy(data, [
  function (item) { return item.sortData.a; },
  function (item) { return item.sortData.b; }
], ["asc", "desc"]);
Run Code Online (Sandbox Code Playgroud)

这将首先按属性进行排序a,对于具有相同属性值的对象a,将按属性降序对它们进行排序b.

它的工作原理是在预期的时间ab性质有不同的类型.

这是使用此语法的jsbin示例.

  • 太棒了,这个答案对我帮助很大! (2认同)

Tom*_*rda 18

_.sortByAll在lodash版本3中有一个方法:

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 }
// ];
Run Code Online (Sandbox Code Playgroud)


Kim*_*Kha 12

令人敬畏的简单方法是:

_.sortBy(data, [function(item) {
    return item.sortData.a;
}, function(item) {
    return item.sortData.b;
}]);
Run Code Online (Sandbox Code Playgroud)

我发现它从检查lodash的源代码,它总是逐个检查功能.

希望有所帮助.

  • 此外,如果您希望对这些排序函数中的任何一个进行"反向"排序,只需在返回的值中添加" - "即可.`return -item.sortData.a;`例如. (2认同)

Cem*_*nlı 9

使用ES6简单的语法和lodash

sortBy(item.sortData, (item) => (-item.a), (item) => (-item.b))
Run Code Online (Sandbox Code Playgroud)

  • 这只是排序时的一种否定方式,因此您无需反转数组。 (2认同)