2011-12-17 75 views
1

我有一個JavaScript對象數組。我想按特定的指標對它們進行排序。在特殊情況下,每次都會有相同的值。下面是一個例子數組:JavaScript [] .sort()方法在應該離開元素時排序

var myArray = [{"key":400686,"metric":999999},{"key":52601288,"metric":999999},{"key":1380180030,"metric":999999},{"key":909661,"metric":999999},{"key":401336,"metric":999999},{"key":1317275,"metric":999999},{"key":8642696,"metric":999999},{"key":1374360020,"metric":999999},{"key":602871933,"metric":999999},{"key":410174,"metric":999999},{"key":503411,"metric":999999},{"key":401511,"metric":999999},{"key":410196,"metric":999999},{"key":419377,"metric":999999},{"key":429167,"metric":999999},{"key":609656,"metric":999999},{"key":837941,"metric":999999},{"key":2410791,"metric":999999},{"key":4501004,"metric":999999},{"key":8633371,"metric":999999},{"key":1356540155,"metric":999999},{"key":1374360757,"metric":999999}]; 

當我做,因爲這調用一樣簡單的東西:

myArray.sort(function(a, b){ return 0; }); 

的數組被排序!它顯然應該保持獨立,因爲排序函數中的返回值0表示相等。

是否有其他人遇到過這個問題?

回答

3

發生這種情況是因爲排序是unstable,它不一定保留相等項目的相對順序。可以使用stable sorting算法,如merge sort

4

0表示相等,這意味着元素是可以互換的。這並不意味着他們不會被移動。這意味着它們可以自由交換或保持原樣,並且數組仍然會被排序。

1

如果要將相同的元素按可預測的順序排序,那麼您需要一個輔助鍵,以便確定哪個元素應位於另一個元素之前。在你的榜樣陣列,您可以使用自定義排序功能,這樣,將第一排序指標,如果這些是相同的,然後按鍵:

myArray.sort(function(a, b){ 
    if (a.metric != b.metric) { 
     return(b.metric - a.metric); 
    } 
    // when metrics are the same, sort by key as secondary sort 
    return(b.key - a.key) 
}); 

或者,如果您想保留了相同的現有秩序元素,那麼你需要一個快速的傳遞給每一次你之前排序添加訂單價值:

// mark each value with it's current position in the array 
for (var i = 0; i < myArray.length; i++) { 
    myArray[i].sortIndexForTies = i; 
} 
myArray.sort(function(a, b){ 
    if (a.metric != b.metric) { 
     return(b.metric - a.metric); 
    } 
    // when metrics are the same, sort by the original array position as second sort key 
    return(b.sortIndexForTies - a.sortIndexForTies) 
}); 
0

我找到了一個不錯的解決辦法,我通過排序參數相加增量我關心的精度外偏置排序在那個參數上。這種偏見使陣列傾向於保持相同的順序。如果距離有一個單位的差異(我的精度在1s位置),那麼該元素得到適當的排序。

for(var i = 0, len = myArray.length, delta = 0; i < len; i++, delta += 0.000001) 
{ 
    myArray[ i ].metric -= delta; 
} 

function byMetric(a, b) 
{ 
    return b.metric - a.metric; 
} 

myArray.sort(byMetric);