11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Javascriptの配列のソートは同じ値の順番は保証されない

Posted at

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
このソートは stable ではありません(訳注:同じ位の値の順番が保証されません)。

Javascriptのsort関数は、ブラウザごとの実装がそれぞれ異なっているようで、
比較関数をちゃんと書かないと、同じコードでも違った出力となってしまう(!)

NG example 1

var array = [{ id: 0, value: 2 }, { id: 1, value: 1 }, { id: 2, value: 1 }] 
var compareFunc = function(a, b) {
  return a.value > b.value ? 1 : -1
}

array.sort(compareFunc)

// chrome firefox
// array = [{ id: 1, value: 1 }, { id: 2, value: 1 }, { id: 0, value: 2 }]

// safari
// array = [{ id: 2, value: 1 }, { id: 1, value: 1 }, { id: 0, value: 2 }]

NG example 2

var array = [{ id: 0, value: 2 }, { id: 1, value: 1 }, { id: 2, value: 1 }] 
var compareFunc = function(a, b) {
  return a.value >= b.value ? 1 : -1
}

array.sort(compareFunc)

// chrome firefox
// array = [{ id: 2, value: 1 }, { id: 1, value: 1 }, { id: 0, value: 2 }]

// safari
// array = [{ id: 1, value: 1 }, { id: 2, value: 1 }, { id: 0, value: 2 }]

OK example

var array = [{ id: 0, value: 2 }, { id: 1, value: 1 }, { id: 2, value: 1 }] 
var compareFunc = function(a, b) {
  if (a.value > b.value) return 1
  if (a.value < b.value) return -1
  return 0
}

array.sort(compareFunc)

// chrome firefox
// array = [{ id: 1, value: 1 }, { id: 2, value: 1 }, { id: 0, value: 2 }]

// safari
// array = [{ id: 1, value: 1 }, { id: 2, value: 1 }, { id: 0, value: 2 }]

比較関数で、「return 0」をちゃんと定義すると主要なブラウザでは、
値が同じ時の順番は元の配列の順番を保持してくれるようです。

このArray.prototype.sort関数に関しては、
mochaなどのテスティングフレームワークのテストは通っていても、
ブラウザでは挙動が違うということもあるので要注意です。

11
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?