JavaScript の Array#sort で return 0 すると要素の順番は不定になります
qiita.com を拝見してました。心当たりがあるのでメモ程度に。
JavaScript の Array#sort は仕様的に非安定ソートで、実際もそうです。実装により異なる結果が得られます。
より具体的には、 [...].sort(function(a, b) { return 0; }); と評価関数の中で return 0 してしまうと要素の順番は保証されません。
return 0 を使わずに記述してください。
この問題については、 http://ofb.net/~sethml/is-sort-stable.html を参照していただくと学びがあります。
以下は僕のツイートを Array#sort で検索した時にでてくる駄文です。見事にいい感じに苦しんでますね。みなさんは気をつけてください。😃
モジュールの依存関係を解決する部分のロジックは8回ほど書き直しました。確かにあれ全く簡単じゃない。あと Array#sort が環境によってオーダーを維持しないのに泣かされた
— コラーゲンたっぷりさん (@uupaa) 2015, 5月 14
Array#sort(評価関数).reverse() の実行結果と
Array#reverse().sort(評価関数) の結果が違うので頭抱えてる
— コラーゲンたっぷりさん (@uupaa) 2014, 5月 19
Array#sort の計算量はブラウザが採用しているソートアルゴリズムに依存するため、計算量のサンプリングを行っておくと、ブラウザ判定できそうね
— コラーゲンたっぷりさん (@uupaa) 2013, 12月 9
Array#sort のアルゴリズムが
Firefox だと MergeSort で、WebKit だと SelectionSort で、V8 が QuickSort って、まじか…
— コラーゲンたっぷりさん (@uupaa) 2013, 12月 9
続き: console.log(Object.freeze([1,2,3]).sort()) →Firefox&IE10:Error,WebKit:[1,2,3],iOS5.1:[1,2,3],Chrome:[3,1,2],Chrome for android:[2,3,1]
— コラーゲンたっぷりさん (@uupaa) 2012, 11月 3
おぃぃ? Chrome stable & canary で a=Object.freeze([1,2,3]) で作った配列に Array#sort() すると、エラーにならないどころか毎回値の順番変わってる! というか Array#sort() がイカれてるがな…
— コラーゲンたっぷりさん (@uupaa) 2012, 11月 3
↑ これ後日修正されました
V8は無茶して速度を稼いでいるかと思ったら、とてもクリアなコードで驚く。
parseInt() などの何気ないに関数に、最適化に関するヒントが書かれていたり、Array.sort()が二種類のソースアルゴリズムを積んでたりと、かなり勉強させていただいた感じ。
— コラーゲンたっぷりさん (@uupaa) 2009, 5月 30
不定、それはパルプンテ
不定は「何が起きてもおかしくない」「恐らく貴方の想像を超える結果をもたらす」という意味で使っています。