這些答案都不是理想的通用方法,用於在排序中使用多個字段。上述所有方法效率不高,因爲它們要麼需要多次對數組進行排序(在足夠大的列表中可能會使事情減慢很多),或者它們會產生大量的虛擬機清理所需的垃圾對象(並且最終會減慢該程序下降)。
這裏的一個解決方案,快速,高效,容易地允許反向排序,並且可以與underscore
或lodash
,或直接用於與Array.sort
最重要的部分是compositeComparator
方法,該方法比較器的陣列函數並返回一個新的複合比較器函數。
/**
* 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);
});
}
你還需要一個比較器函數來比較你想排序的字段。 naturalSort
函數將創建一個給定特定字段的比較器。編寫一個反向排序的比較器也是微不足道的。
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;
}
}
(所有的代碼到目前爲止是可重複使用,並且可以保存在應用模塊,例如)
接下來,你需要創建複合比較。對於我們的示例,它將如下所示:
var cmp = compositeComparator([naturalSort('roomNumber'), naturalSort('name')]);
這將按房間號排序,然後是名稱。添加其他排序標準並不重要,不會影響排序的性能。
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);
返回以下
[ { name: 'Chris', roomNumber: 1, bedNumber: 1 },
{ name: 'Lisa', roomNumber: 2, bedNumber: 2 },
{ name: 'Omar', roomNumber: 2, bedNumber: 1 },
{ name: 'John', roomNumber: 3, bedNumber: 1 } ]
我喜歡這種方法是,它允許快速排序的字段任意數量,不會產生大量的垃圾或執行排序中字符串連接的原因並且可以輕鬆地使用,以便某些列反向排序,而訂單列使用自然排序。
有一個[博客文章](http://blog.falafel.com/nifty-underscore-tricks-sorting-by-multiple-properties-with-underscore/)擴展了這一點,幷包括有關排序升序和降序屬性。 – 2014-10-07 15:13:51
+1:我認爲這應該是被接受的答案:o) – Andrew 2014-10-21 04:05:32
正是我所期待的。謝謝! – 2015-11-07 15:14:30