[英]JavaScript Sort Array of Objects by Multipe Fields in Chrome
話雖如此,聽起來很簡單,但是我沒有成功在Chrome中達到完美的效果(我在IE中做到了)
所以我有一個對象:
var objs=[
{ name: "water", type: "cold" },
{ name: "tea", type: "hot" },
{ name: "coffee", type: "hot" },
{ name: "choco", type: "cold" }
];
我按名稱對其進行了升序排列,並得到了預期的結果:
我在IE和Chrome上都得到了相同的結果,
然后,我再次按類型,升序和期望對它進行排序:
但是我只在IE中獲得了預期的結果,而在Chrome中,結果幾乎是相同的,只是“水”位於頂部(它破壞了第一次排序)
任何一般的方法想法? (我需要在每個字段中保持一個函數調用,而不是同時在一個函數中按多個字段進行排序)
我的排序方法是這樣的:
function SortBy(key,Asc,method){
var GetKey=function(x) {return method ? method(x[key]) : x[key] };
return function(a,b){
var A=GetKey(a), B=GetKey(b);
return ((A<B) ? -1 : ((A>B) ? 1 : 0)) * [-1,1][+!!Asc];
}
}
var sortedObjects=Clone(objs); //clone the current objs
sortedObjects.sort(SortBy("name" , true, function(x){
if (typeof(x)=="string") return x.toLowerCase(); else return x;
}));
objs=sortedObjects; //got the first result
sortedObjects.sort(SortBy("type",true,function(x){
if (typeof(x)=="string") return x.toLowerCase(); else return x;
}));
objs=sortedObjects;
此處編輯的是小提琴(問題是“水”): DEMO
如果我們閱讀ES5規范 §15.4.4.11Array.prototype.sort ,則第二句話指出
排序不一定是穩定的(也就是說,比較相等的元素不一定保持其原始順序)
也就是說,在JavaScript中 ,如果比較器說兩件事相等(給出0
),則它們是否被交換並不重要,因此,在某些環境中,它們可能由於其他原因(例如哈希)而被交換或只是實施。
即,您所體驗到的結果是規范定義的有效sort
結果,並且每次重復相同的sort
甚至可能會得出不同的結果
希望我不會對此感到失望,但是如果您將其作為一個函數來完成,則無需遍歷數組多次,並且可以避免意外的結果
/* list = multiSort(list [, obj, ...])
* where e.g. obj = {
* key: "keyToLookAt",
* optional comparator: function (a, b) {return a<b || ((a===b)-1);},
* optional ascending: default true
* }
*/
var multiSort = (function () {
function generateSorter(key, comparator, ascending) {
ascending = 2 * !!ascending - 1;
if (comparator) {
return function sorter(a, b) {
return ascending * comparator(a[key], b[key]);
};
}
return function sorter(a, b) {
a = a[key];
b = b[key];
return ascending * (a < b ? -1 : a > b ? 1 : 0);
};
}
function sortManager(sorters) {
return function (a, b) {
var ret, i = 0;
for (; i < sorters.length; ++i) {
ret = sorters[i](a, b);
if (ret !== 0) return ret;
}
return 0;
};
}
function multiSort(list) {
var i = 1, sorters = [];
for (; i < arguments.length; ++i) {
sorters.push(generateSorter(
arguments[i].key,
arguments[i].comparator,
'ascending' in arguments[i] ? arguments[i].ascending : 1
));
}
list.sort(sortManager(sorters));
return list;
}
return multiSort;
}());
然后在使用它時,“最嚴格”的排序規則首先出現
multiSort(
[
{ name: "water", type: "cold" },
{ name: "tea", type: "hot" },
{ name: "coffee", type: "hot" },
{ name: "choco", type: "cold" }
],
{key: 'type'},
{key: 'name'}
);
/*
[
{ "name": "choco" , "type": "cold" },
{ "name": "water" , "type": "cold" },
{ "name": "coffee", "type": "hot" },
{ "name": "tea" , "type": "hot" }
]
*/
我創建了一個CodePen來測試和正常工作...我用更易讀的代碼編寫了相同的想法
function SortBy(key, isAsc, fn){
fn = fn || function (x){ return x; };
return function(objA, objB){
var a = fn(objA[key]);
var b = fn(objB[key]);
var isGreater = isAsc ? 1 : -1;
var isLesser = -isGreater;
var isSame = 0;
if( a > b ) return isGreater;
if( a == b ) return isSame;
if( a < b ) return isLesser;
return -1; //to down the undefined
}
}
http://codepen.io/anon/pen/sGgDq編輯並測試了大量數據
ps:我使用了codepen,因為jsfiddle無法在我的工作中打開
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.