关于javascript:如何使用underscore.js进行asc和desc排序?

How can I do an asc and desc sort using underscore.js?

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


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

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

但是您可以使用.reverse方法将其降序:

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

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

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

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

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

1
2
3
4
5
6
7
8
9
// 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;
});


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

1
2
3
4
5
6
7
8
9
10
//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值。

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


Array原型的reverse方法修改数组并返回对其的引用,这意味着您可以执行以下操作:

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

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

In addition, the Array prototype's methods are proxied through the chained Underscore object, so you can slip a reverse or a push into your chain, and continue to modify the array.

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

1
2
3
4
5
var sortedDescAndFiltered = _.chain(collection)
    .sortBy('propertyName')
    .reverse()
    .filter(_.property('isGood'))
    .value();


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

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

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


下划线Mixins

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

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

Mixin.js

1
2
3
4
5
6
7
8
9
10
11
_.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;
      }
    }
})

使用范例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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>"
)
  _.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:用于SortBy Mixin的JSFiddle