Không có câu trả lời nào trong số này là lý tưởng cho phương pháp mục đích chung để sử dụng nhiều trường trong một loại. Tất cả các cách tiếp cận ở trên đều không hiệu quả vì chúng yêu cầu sắp xếp mảng nhiều lần (trong danh sách đủ lớn có thể làm chậm mọi thứ) hoặc chúng tạo ra một lượng lớn các đối tượng rác mà VM sẽ cần dọn dẹp (và cuối cùng là làm chậm chương trình xuống).
Đây là một giải pháp nhanh chóng, hiệu quả, dễ dàng cho phép sắp xếp ngược và có thể được sử dụng với underscore
hoặc lodash
, hoặc trực tiếp vớiArray.sort
Phần quan trọng nhất là compositeComparator
phương thức, lấy một mảng các hàm so sánh và trả về một hàm so sánh hỗn hợp mới.
/**
* Chains a comparator function to another comparator
* and returns the result of the first comparator, unless
* the first comparator returns 0, in which case the
* result of the second comparator is used.
*/
function makeChainedComparator(first, next) {
return function(a, b) {
var result = first(a, b);
if (result !== 0) return result;
return next(a, b);
}
}
/**
* Given an array of comparators, returns a new comparator with
* descending priority such that
* the next comparator will only be used if the precending on returned
* 0 (ie, found the two objects to be equal)
*
* Allows multiple sorts to be used simply. For example,
* sort by column a, then sort by column b, then sort by column c
*/
function compositeComparator(comparators) {
return comparators.reduceRight(function(memo, comparator) {
return makeChainedComparator(comparator, memo);
});
}
Bạn cũng sẽ cần một hàm so sánh để so sánh các trường bạn muốn sắp xếp. Các naturalSort
chức năng sẽ tạo ra một so sánh được đưa ra một lĩnh vực cụ thể. Viết một bộ so sánh để sắp xếp ngược cũng là chuyện nhỏ.
function naturalSort(field) {
return function(a, b) {
var c1 = a[field];
var c2 = b[field];
if (c1 > c2) return 1;
if (c1 < c2) return -1;
return 0;
}
}
(Ví dụ, tất cả các mã đều có thể tái sử dụng và có thể được giữ trong mô-đun tiện ích)
Tiếp theo, bạn cần tạo bộ so sánh tổng hợp. Ví dụ của chúng tôi, nó sẽ trông như thế này:
var cmp = compositeComparator([naturalSort('roomNumber'), naturalSort('name')]);
Điều này sẽ sắp xếp theo số phòng, theo sau là tên. Thêm tiêu chí sắp xếp bổ sung là không đáng kể và không ảnh hưởng đến hiệu suất của loại.
var patients = [
{name: 'John', roomNumber: 3, bedNumber: 1},
{name: 'Omar', roomNumber: 2, bedNumber: 1},
{name: 'Lisa', roomNumber: 2, bedNumber: 2},
{name: 'Chris', roomNumber: 1, bedNumber: 1},
];
// Sort using the composite
patients.sort(cmp);
console.log(patients);
Trả về như sau
[ { name: 'Chris', roomNumber: 1, bedNumber: 1 },
{ name: 'Lisa', roomNumber: 2, bedNumber: 2 },
{ name: 'Omar', roomNumber: 2, bedNumber: 1 },
{ name: 'John', roomNumber: 3, bedNumber: 1 } ]
Lý do tôi thích phương pháp này là vì nó cho phép sắp xếp nhanh trên một số trường tùy ý, không tạo ra nhiều rác hoặc thực hiện nối chuỗi bên trong sắp xếp và có thể dễ dàng sử dụng để một số cột được sắp xếp ngược trong khi các cột theo thứ tự sử dụng sắp xếp