2014-04-08 14 views
76

Có một phương pháp tiện lợi để sắp xếp một mảng của các đối tượng dựa trên một số thuộc tính:lodash nhiều cột SortBy giảm dần

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

Tuy nhiên đó là chỉ cho tăng dần phân loại. Có cách nào tiện dụng để xác định hướng cho mỗi cột? Ví dụ.

var data = _.sortBy(array_of_objects, [{'type': 'asc'}, {'name': 'desc'}]);

Trả lời

164

Tính đến lodash 3.5.0 bạn có thể sử dụng sortByOrder (đổi tên orderBy trong v4.3.0):

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

Kể từ phiên bản 3.10.0 bạn thậm chí có thể sử dụng ngữ nghĩa tiêu chuẩn để đặt hàng (asc, desc):

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

Trong phiên bản 4 của lodash phương pháp này đã được đổi tên orderBy:

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

Đối với bạn thông tin, chức năng này đã được đổi tên thành _.orderBy (https://lodash.com/docs#orderBy) trong Lodash là 4.3.0. Hàm sắp xếp bình thường được gọi là _.sortBy (https://lodash.com/docs#sortBy) –

+1

Tôi nhận được '_.sortByOrder không phải là một hàm' trong phiên bản mới nhất của lodash. – chovy

+0

Giả sử bạn đang sử dụng lodash 4, 'sortByOrder' không còn tồn tại. Nó bây giờ được đặt tên là 'orderBy' – djskinner

5

Có cách nào tiện dụng để xác định hướng trên mỗi cột không?

Không. Bạn không thể chỉ định thứ tự sắp xếp ngoài chức năng gọi lại ngược giá trị. Thậm chí điều này cũng không thể cho một loại đa hướng.

Bạn có thể có thể làm

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

Đối với mọi thứ khác, bạn sẽ cần phải sử dụng tới nguồn gốc .sort() với một chức năng so sánh tùy chỉnh:

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

Bạn luôn có thể sử dụng Array.prototype.reverse()

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

ha thats thông minh. một số loại tăng dần (mặc định lodash giảm dần) Tôi đã sử dụng điều này: _.sortBy (array_of_objects, "some_numerical_value_key") đảo ngược() – devonJS

+8

yep, có thể, nhưng nó không quá tốt về hiệu suất ... – BotanMan

+1

Trong khi tốt đủ cho một số trường hợp, hiệu quả của việc này là để sắp xếp giảm dần trên BOTH cột, mà không phải là những gì câu hỏi yêu cầu. – Inkling

9

Cần lưu ý rằng nếu bạn muốn sắp xếp các thuộc tính cụ thể giảm dần, bạn không muốn chỉ cần nối thêm .reverse() ở cuối, vì điều này sẽ làm cho tất cả các loại giảm dần.

Để làm cho các loại cụ thể giảm dần, hãy chuỗi các loại của bạn từ ít quan trọng nhất đến đáng kể nhất, gọi .reverse() sau mỗi loại mà bạn muốn giảm dần.

var data = _(data).chain() 
    .sort("date") 
    .reverse() // sort by date descending 
    .sort("name") // sort by name ascending 
    .result() 

Vì loại _ là loại ổn định, bạn có thể an toàn chuỗi và đảo ngược các loại vì nếu hai mục có cùng giá trị cho một thuộc tính thì thứ tự của chúng được giữ nguyên.

More information

+0

Nếu bạn không có đủ đại diện để bình luận, đừng bình luận. Mặc dù bạn đã tìm ra câu trả lời thực sự, điều này rất tốt, nhưng bạn thậm chí không cần phải đề cập đến thực tế đó. – ArtOfCode

1

Trong tài liệu hướng dẫn của phiên bản 4.11.x, nói: ` "Phương pháp này cũng giống như _.sortBy ngoại trừ việc nó cho phép xác định sắp xếp thứ tự của các iterate để sắp xếp theo. Nếu đơn đặt hàng không được chỉ định, tất cả các giá trị sẽ được sắp xếp theo thứ tự tăng dần. Nếu không, hãy chỉ định thứ tự "desc" cho giảm dần hoặc "asc" cho thứ tự sắp xếp tăng dần của các giá trị tương ứng." (nguồn https://lodash.com/docs#sortBy)

let sorted = _.sortBy(this.items, ['fieldFoo', 'fieldBar'], ['asc', 'desc'])

+0

Tôi nghĩ bạn muốn sử dụng '_.sortByOrder'? –

4

sâu lĩnh vực & đa lĩnh vực & khác nhau hướng đặt hàng Lodash> 4

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

Thực ra đây sẽ là câu trả lời ngay bây giờ. sortBy không cung cấp cho bạn hướng, nhưng orderBy làm. – moplin

1

Bạn cũng có thể thử điều này:

var data= _.reverse(_.sortBy(res.locals.subscriptionList.items, ['type', 'name'])); 
Các vấn đề liên quan