2015-07-03 112 views
14

假設我有此數組:排序數組項,並保留相同的要素的順序

array.sort(function(a, b) { 
    if (a.name < b.name) return -1; 
    if (a.name > b.name) return 1; 
    return 0; 
}); 

而且ECMAScript language specifications that tell me that

var array = [ 
    { name: "border-color", value: "#CCCCCC" }, 
    { name: "color", value: "#FFFFFF" }, 
    { name: "background-color", value: "rgb(0, 0, 0)" }, 
    { name: "background-color", value: "rgba(0, 0, 0, .5)" } 
]; 

而且此功能可將陣列的名字排序

排序不一定穩定(也就是說,比較 相等的元素不一定保持其原始順序)。

因此,排序後,這兩個項目與NAME =背景顏色可以按任何順序出現,即:

[ 
    { name: "background-color", value: "rgb(0, 0, 0)" }, 
    { name: "background-color", value: "rgba(0, 0, 0, .5)" }, 
    ... 
] 

或者

[ 
    { name: "background-color", value: "rgba(0, 0, 0, .5)" }, 
    { name: "background-color", value: "rgb(0, 0, 0)" }, 
    ... 
] 

我怎樣才能陣列,這樣對項目排序同名保持相對順序?我寧願不硬編碼任何東西。

+0

退房這個答案短ES6實現穩定排序的:https://stackoverflow.com/a/48660568/1260020 – simo

回答

14

理論上,在排序之前,您可以跟蹤其在數組中的索引,並在排序時將其考慮在內。

var sortArray = yourarray.map(function(data, idx){ 
    return {idx:idx, data:data} 
}) 

sortArray.sort(function(a, b) { 
    if (a.data.name < b.data.name) return -1; 
    if (a.data.name > b.data.name) return 1; 
    return a.idx - b.idx 
}); 

var answer = sortArray.map(function(val){ 
    return val.data 
}); 
+3

你從哪裏得到'idx'? –

+1

良好的捕獲,修復了地圖函數中參數的名稱 – noveyak

+0

@noveyak由於數組包含引用類型objet,因此可以在排序函數中確定元素的索引。所以我們在排序前後避免地圖。 – Psddp

0

添加一個額外的屬性數組:爲了

var array = [ 
    { name: "border-color", value: "#CCCCCC", order: 1 }, 
    { name: "color", value: "#FFFFFF", order: 2 }, 
    { name: "background-color", value: "rgb(0, 0, 0)", order: 3 }, 
    { name: "background-color", value: "rgba(0, 0, 0, .5)", order: 4 } 
]; 

,然後更改排序功能進行排序順序名稱是否相同:

array.sort(function(a, b) { 
    if (a.name < b.name) return -1; 
    if (a.name > b.name) return 1; 
    if (a.name == b.name) { 
     if(a.order > b.order) return -1; else return 1; 
    } 
}); 

注意標誌的訂單回報必須根據您希望排序是遞增還是遞減來進行調整(在這裏,我假設您正在按照從大到小的順序進行排序,因此請返回小訂單的排序)。

+1

你不是指'如果(a.name == b.name)' – Cyclonecode

+1

我不能相信我錯過了這個oO,即使經過了所有這些年的編碼...... –

+2

不需要使用'else',返回聲明。你可以做'if(a.order> b.order)返回-1;返回1;'。你也可以刪除包含'if(a.name == b.name){}'語句,它在執行時總是爲真(因爲它不是'>'或'<')。 – blex

2

由於數組包含引用類型objet,因此可以在排序函數中確定元素的索引。所以我們在排序前後避免地圖。

sortArray.sort((function(a, b) { 
    if (a.name < b.name) return -1; 
    if (a.name > b.name) return 1; 
    return this.indexOf(a) - this.indexOf(b); 
}).bind(sortArray)); 
+0

這是不是很慢,因爲它必須每次都找到索引? – Vic

相關問題