lodash多列排序sortBy

194

有一种巧妙的方法可以基于多个属性对对象数组进行排序:

var data = _.sortBy(array_of_objects, ['type', 'name']);

然而,这仅适用于升序排序。是否有一种方便的方法可以按列定义排序方向?例如:
var data = _.sortBy(array_of_objects, [{'type': 'asc'}, {'name': 'desc'}]);
7个回答

413

lodash 3.5.0 开始,您可以使用sortByOrder(在v4.3.0中改名为orderBy):

var data = _.sortByOrder(array_of_objects, ['type','name'], [true, false]);

3.10.0版本开始,您甚至可以使用标准的语义来进行排序(升序,降序):


var data = _.sortByOrder(array_of_objects, ['type','name'], ['asc', 'desc']);

版本4的lodash中,这个方法已被重命名为orderBy

var data = _.orderBy(array_of_objects, ['type','name'], ['asc', 'desc']);

10
提供给您的信息是,自 Lodash 4.3.0 版本起,此函数已更名为 _.orderBy(https://lodash.com/docs#orderBy)。普通排序函数被称为 _.sortBy(https://lodash.com/docs#sortBy)。 - Nidhin David
2
在最新版本的lodash中,我遇到了_.sortByOrder不是一个函数的问题。 - chovy
70
为什么lodash一直在改变函数名称? - Kenny Worden
27
使用 lodash@4.17.10 版本时,['asc', 'desc']这一部分对我来说被忽略了。所有元素都是按升序排序的。 - maninak
10
这是针对_.sortBy的。请尝试使用_.orderBy代替。希望这有所帮助。 - pcasme
显示剩余3条评论

59

您总是可以使用Array.prototype.reverse()

var data = _.sortBy(array_of_objects, ['type', 'name']).reverse();

哈哈,这很聪明。为了进行数字升序排序(lodash默认降序),我使用了以下代码:_.sortBy(array_of_objects, "some_numerical_value_key").reverse() - devonj
3
虽然在某些情况下该方法足够好,但其效果是对两列数据同时进行降序排列,而这并不符合问题的要求。 - Inkling

16

深度字段 & 多字段 & 不同方向 排序 Lodash >4

var sortedArray = _.orderBy(mixedArray,
                            ['foo','foo.bar','bar.foo.bar'],               
                            ['desc','asc','desc']);

实际上,现在这就是答案。sortBy 不会给出排序方向,但 orderBy 会。 - Pablo Palacios

15
值得注意的是,如果你想要对特定的属性进行降序排序,不要简单地在末尾添加 .reverse(),因为这将使所有的排序都变成降序。
为了让特定的排序变成降序,从最不重要的属性开始链式调用排序方法,每个你想要降序的排序后面加上 .reverse()。
var data = _(data).chain()
    .sort("date")
    .reverse()    // sort by date descending
    .sort("name") // sort by name ascending
    .result()

由于Underscore的排序是稳定的,因此您可以安全地链接和反转排序,因为如果两个项目对于某个属性具有相同的值,则它们的顺序会被保留。

更多信息


9
在版本4.11.x的文档中,有这样一段话: " 除了允许指定排序依据的排序方法之外,此方法与_.sortBy类似。如果未指定orders,则所有值按升序排序。否则,对应值的排序顺序为"desc"表示降序或"asc"表示升序。 (来源https://lodash.com/docs/4.17.10#orderBy)" let sorted = _.orderBy(this.items, ['fieldFoo', 'fieldBar'], ['asc', 'desc'])意思是将this.items按照'fieldFoo'和'fieldBar'这两个字段进行排序,其中'fieldFoo'按照升序排列,'fieldBar'按照降序排列。

我想你的意思是使用_.sortByOrder - AJ Richardson
找不到变量 _。 - Vishal Vaghasiya

5

有没有一种方便的方法来为每列定义排序方向?

没有。除了通过反转数值的回调函数指定排序顺序之外,您无法指定排序顺序。对于多列排序,甚至这也不可能。

您可能可以这样做:

 _.each(array_of_objects, function(o) {
     o.typeDesc = -o.type; // assuming a number
 });
 _.sortBy(array_of_objects, ['typeDesc', 'name'])

对于其他的情况,您需要使用带有自定义比较函数的原生.sort()

 array_of_objects.sort(function(a, b) {
     return a.type - b.type // asc
         || +(b.name>a.name)||-(a.name>b.name) // desc
         || …;
 });

0

你也可以尝试这个:

var data= _.reverse(_.sortBy(res.locals.subscriptionList.items, ['type', 'name']));

1
这会比仅使用_.orderBy慢得多。 - reggaeguitar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接