2013-03-24 104 views
0

我需要排序一個數組,但它只能在Chrome中正常工作。在Mozilla的規範,我發現這個文本但仍無法修復此:排序()在mozilla&opera中無法正常工作

「這個數組的元素進行排序排序不一定 穩定(即,比較相等不一定留元素如果comparefn不是未定義的,則它應該是 函數,它接受兩個參數x和y,並返回一個負值 如果x < y,如果x = y則爲零,如果x> y則返回正值, Y「。

而這個鏈接https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort可能是它會幫助你,我

這是我的代碼

arr.sort(sortTrip); 

function sortTrip(a, b) { 

    if (a.to != b.from) return 1; 
    if (a.to == b.from) return -1; 

} 

這是arr

var arr = [ 
    { 
     "from": "Moscow", 
     "to": "Rome", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Oslo", 
     "to": "Paris", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Helsinki", 
     "to": "Tokio", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Tokio", 
     "to": "Moscow", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Paris", 
     "to": "New-York", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Rome", 
     "to": "Oslo", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    } 
] 

結果必然是

  • 赫爾辛基 - 東京
  • 東京 - 莫斯科
  • 莫斯科 - 羅馬
  • 羅馬 - 奧斯陸
  • 奧斯陸 - 巴黎
  • 巴黎 - 新紐約
+1

護理提供有效的輸入,你得到了不同的結果? – 2013-03-24 15:55:02

+0

當然,在瀏覽器和Mozilla的歌劇 – 2013-03-24 16:00:32

+0

不同的結果,它清楚地說,你需要返回-1,0和1,所以當a.to == b.from它應該是0,而當a.to TheBrain 2013-03-24 16:03:09

回答

0

我的其他答案解釋了爲什麼你的排序不穩定。這一個將解決你的實際問題:-)

你不能使用sort這種類型的問題,你想從一組(無序)的邊緣構造節點的列表。對數組進行排序僅適用於如果可以將比較兩個元素而沒有附加數據。假設你只有兩個連接Tokio - MoscowRome - Oslo,你不知道他們哪一個先來(不聯繫你的計劃,但你還沒有)。相比之下,比較數字時,您可以輕鬆並始終告訴5大於3(通過計算差異)。

相反,我們需要做的是這樣thisthis - 建立一個結構,我們可以很容易地通過名稱訪問的站點和循環它們在直接插入連接時,我們遇到了他們,讓最終我們有一個列表

var map = {}; 
for (var i=0; i<arr.length; i++) { 
    var con = arr[i]; 
    map[con.from] = con; 
} 

所以,我們現在可以構建您的路線某種鏈表:

for (var from in map) { 
    var connTo = map[from].to; 
    if (connTo in map) 
     map[from].next = map[connTo]; 
} 

及刪去從地圖上所有目的地找到啓動站:由站連接

for (var from in map) 
    for (var next = map[from]; next; next = next.next) 
     delete map[next.to]; 
for (from in map) // there's only one key left 
    var start = from; // "Helsinki" 

讓我們構建的路由作爲站名的數組:

var route = [start], 
    conn = map[start]; 
while (conn) { 
    route.push(conn.to) 
    conn = conn.next; 
    // maybe delete conn.next as we don't need it any more 
} 
// route: 
// ["Helsinki", "Tokio", "Moscow", "Rome", "Oslo", "Paris", "New-York"] 

或結果是你想要的,連接列表:

var arr = []; 
for (var conn = map[start]; conn; conn = conn.next) 
    arr.push(conn); 

有了這樣的計劃,我們現在甚至可以構造一個比較函數來對原始數組進行排序:

arr.sort(function(a, b) { 
    // compare the positions of the departure stations in the route 
    return route.indexOf(a.from) - route.indexOf(b.from); 
}); 
+0

它是genious。真。感謝您對本精彩的回答,你救了我的大腦在安全) – 2013-03-24 18:25:32

+0

以及我發現我不太明白這個片段:'爲(VAR從地圖) 爲(VAR下一=地圖[從];未來;未來= next.next) 刪除地圖[下一個。至]; (從地圖上) var start = from;'我想了解它是如何工作的,但在這個野生循環中感到困惑'(var next = map [from]; next; next = next.next)' – 2013-03-25 06:45:41

+0

我可以在沒有刪除的情況下找到開始的地方,但用'if'可以找到起始地的名字不是到達地的名字之一嗎? – 2013-03-25 07:09:15

4

參見Sorting in JavaScript: Should every compare function have a "return 0" statement?


if (a.to != b.from) return 1; 
if (a.to == b.from) return -1; 

這不是一個一致的比較函數(違反了反身性,即compare(x, x) == 0,例如)。你期望它做什麼?

引述ES5.1 spec on sort

如果comparefn是[...]不是此數組的元素一致的比較函數,排序行爲是實現定義。

函數comparefn是一組值S的一致比較函數,如果所有的下面在設定S滿足所有值ab,和c(可能是相同的值)的要求:符號a <CF b裝置comparefn(a,b) < 0; a =CF b表示comparefn(a,b) = 0(任一符號);和a >CF b表示comparefn(a,b) > 0

調用comparefn(a,b)給出了具體的一對值ab作爲它的兩個參數的時總是返回相同的值v。此外,Type(v)是Number,並且v不是NaN。請注意,這意味着a <CF b,a =CF ba >CF b中的一個對於給定的一對ab將是正確的。

  • 調用comparefn(a,b)不會修改此對象。
  • (自反)
  • 如果a =CF b,然後b =CF a(對稱)
  • 如果a =CF bb =CF c,然後a =CF c(的=CF傳遞性)
  • 如果a <CF bb <CF c,然後a <CF c(的<CF傳遞性)
  • 如果a >CF bb >CF c,則a >CF c(傳遞性爲>CF

注意:上述的條件是必要的,足以確保comparefn劃分集合S成等價類,並且這些等價類全序。

+1

我認爲不止於此,它是不是一個有效的comparefn(A,B),根據該規範,因爲它並不適用於例如反身性(http://es5.github.com/# x15.4.4.11)ie compareTo(a,a)不是0 – 2013-03-24 16:02:06

+0

這看起來像是塑造成一個有趣的答案。爲了幫助您解決這個問題,請在v8中進行排序Chrome https://code.google.com/p/v8/source/browse/trunk/src/array.js(這是針對較小陣列和QuickSort的插入排序對於較大的),Spidermonkey使用合併排序https://github.com/funkaster/spidermonkey/blob/master/js/src/ds/Sort.h – 2013-03-24 16:07:49

+0

@Benjamin:完全。也違反了'> CF'的傳遞性。 – Bergi 2013-03-24 16:08:08

相關問題