如何使用underscore.js进行升序和降序排序?


166

我目前正在使用underscorejs进行json排序。现在,我要求使用underscore.js 进行ascendingdescending排序。我在文档中没有看到与此相同的任何内容。我该如何实现?


1
请添加一个示例,说明您正在排序以及如何进行排序。
2013年

你在排序什么?数字?琴弦?日期?还有吗
亩太短了,

@muistooshort我正在排序对象数组。因此,sortBy方法非常适合我的标准,可以升序排序,反之则不行。
拉胡尔

如果您按数字排序,那么您的sortBy函数可以是,return -n但不适用于字符串。因此,有关您正在排序的事物的问题。
mu太短了

2
使用Lodash可以使用简写形式,_.sortBy([1,4,3,2]).reverse()或者_.chain([1,4,3,2]).sortBy().reverse().value()如果您不想使用reverse()Array 的原型。
GFoley83 2014年

Answers:


363

您可以使用.sortBy,它将始终返回一个升序列表:

_.sortBy([2, 3, 1], function(num) {
    return num;
}); // [1, 2, 3]

但是您可以使用.reverse方法使它降序

var array = _.sortBy([2, 3, 1], function(num) {
    return num;
});

console.log(array); // [1, 2, 3]
console.log(array.reverse()); // [3, 2, 1]

或者在处理数字时,在返回值前添加负号以使列表下降:

_.sortBy([-3, -2, 2, 3, 1, 0, -1], function(num) {
    return -num;
}); // [3, 2, 1, 0, -1, -2, -3]

引擎盖下.sortBy使用内置的.sort([handler])

// Default is ascending:
[2, 3, 1].sort(); // [1, 2, 3]

// But can be descending if you provide a sort handler:
[2, 3, 1].sort(function(a, b) {
    // a = current item in array
    // b = next item in array
    return b - a;
});

9
最后的解决方案,即在返回的num上添加消极符号是完美的。
vinesh 2014年

您为什么会认为这是泡沫排序?.sortBy()内置的内幕调用Array.sort(),其算法取决于浏览器供应商,但是气泡排序几乎不是他们的选择。
Rene Saarsoo,2015年

这不会增加时间复杂度吗?它使列表被排序两次。
user1477388 '16

@ user1477388我不确定您对两次排序的意思是什么?
andlrc '16

@andlrc因此,当您调用时_.sortBy(arr, function),我假设它在每个项目上循环并执行一些逻辑以返回排序后的数组。然后,当您调用Array.prototype.reverse()它时,它可能会再次遍历每个项目并执行一些逻辑以返回反向数组。因此,您要循环两次数组。
user1477388 '16

57

使用下划线的降序可以通过将返回值乘以-1来完成。

//Ascending Order:
_.sortBy([2, 3, 1], function(num){
    return num;
}); // [1, 2, 3]


//Descending Order:
_.sortBy([2, 3, 1], function(num){
    return num * -1;
}); // [3, 2, 1]

如果按字符串而不是数字排序,则可以使用charCodeAt()方法获取unicode值。

//Descending Order Strings:
_.sortBy(['a', 'b', 'c'], function(s){ 
    return s.charCodeAt() * -1;
});

3
我正在尝试按字母顺序排序-乘以-1是无效操作。:)
rythos42

它是一个有价值的用例,但未在问题中指定。但是,将字符串乘以-1是有效的操作。它返回NaN,这是有效的结果。
jEremyB

1
记得也要分配阵列!SOME_ARR = _.sortBy(SOME_ARR,function(num){SOME_FUNC ...});
2014年

4
charCodeAt将“在一个字符串指定索引处返回字符的Unicode”,因此它可以在一个字符串来排序字符,但如确实不能 “之类的字符串”它按字符串中的字符
安东尼

2
这仅按第一个字符排序,并且区分大小写。
艾丹2014年

50

所述阵列原型的反向方法修改该阵列,并返回到它的基准,这意味着你可以这样做:

var sortedAsc = _.sortBy(collection, 'propertyName');
var sortedDesc = _.sortBy(collection, 'propertyName').reverse();

此外,下划线文档的内容为:

另外,数组原型的方法通过链接的Underscore对象代理,因此您可以将a reverse或a push插入链中,并继续修改数组。

这意味着您还可以.reverse()在链接时使用:

var sortedDescAndFiltered = _.chain(collection)
    .sortBy('propertyName')
    .reverse()
    .filter(_.property('isGood'))
    .value();

就最简单的用例而言,这是最简单的反向/降序排序方法。
丹·阿特金森

2
:做一个不区分大小写字母排序_.sortBy(collection, item => item. propertyName.toLowerCase());
- XåpplI'-I0llwlg'I

如果数组中有负数,这将不起作用。
Shruti Kapoor

@ShrutiKapoor是的。为什么不呢?
埃米尔·伦德伯格

5
在性能方面,最好先应用过滤器,然后对(其余)值进行排序。
萨拉(Saran)

12

与Underscore库类似,还有一个名为“ lodash”的库,该库具有一个方法“ orderBy”,该方法接受参数来确定对其排序的顺序。你可以像这样使用它

_.orderBy('collection', 'propertyName', 'desc')

由于某些原因,它没有记录在网站文档中。


我认为您将下划线lodash混淆。只有后者具有提到的orderBy函数
Thomas Marti

是的,我不好 将更新答案。感谢您的指正:)
Minkesh Jain's

orderBy,超级有用!与使用反向相比,它要好得多,因为它保留了我正在寻找的稳定的sort属性。
Flimm

由于某些原因而无法为我工作:其lodash(
aleXela

0

下划线混音

扩展@emil_lundberg的答案,如果您使用Underscore进行排序的自定义函数(如果您可能在某种应用程序中重复这种排序),则还可以编写“ mixin”。

例如,也许您有一个控制器或查看排序结果为“ ASC”或“ DESC”的排序结果,并且想要在该排序之间进行切换,则可以执行以下操作:

Mixin.js

_.mixin({
    sortByOrder: function(stooges, prop, order) {
      if (String(order) === "desc") {
          return _.sortBy(stooges, prop).reverse();
      } else if (String(order) === "asc") {
          return _.sortBy(stooges, prop);
      } else {
          return stooges;
      }
    }
})

使用范例

var sort_order = "asc";
var stooges = [
  {name: 'moe', age: 40}, 
  {name: 'larry', age: 50}, 
  {name: 'curly', age: 60},
  {name: 'July', age: 35},
  {name: 'mel', age: 38}
 ];

_.mixin({
    sortByOrder: function(stooges, prop, order) {
    if (String(order) === "desc") {
        return _.sortBy(stooges, prop).reverse();
    } else if (String(order) === "asc") {
        return _.sortBy(stooges, prop);
    } else {
        return stooges;
    }
  }
})


// find elements
var banner = $("#banner-message");
var sort_name_btn = $("button.sort-name");
var sort_age_btn = $("button.sort-age");

function showSortedResults(results, sort_order, prop) {
    banner.empty();
    banner.append("<p>Sorting: " + prop + ', ' + sort_order + "</p><hr>")
  _.each(results, function(r) {
    banner.append('<li>' + r.name + ' is '+ r.age + ' years old.</li>');
  }) 
}

// handle click and add class
sort_name_btn.on("click", function() {
  sort_order = (sort_order === "asc") ? "desc" : "asc"; 
    var sortedResults = _.sortByOrder(stooges, 'name', sort_order);
  showSortedResults(sortedResults, sort_order, 'name');
})

sort_age_btn.on('click', function() {
    sort_order = (sort_order === "asc") ? "desc" : "asc"; 
    var sortedResults = _.sortByOrder(stooges, 'age', sort_order);
  showSortedResults(sortedResults, sort_order, 'age');
})

这是一个JSFiddle演示:JSFiddle for SortBy Mixin

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.