Array.prototype.sort()

概要

配列の要素をソートします。

構文

array.sort(compareFunction);

引数

compareFunction
ソート順を定義する関数を指定します。省略された場合、配列は各要素の文字列比較に基づき辞書順にソートされます。

説明

compareFunction (比較関数) が与えられなかった場合、要素はそれぞれの文字列に変換したものを比較して辞書 (あるいは電話帳。数的でない) 順にソートされます。例えば、"80" は辞書順では "9" の前に来ますが、数的なソートでは 9 が 80 の前に来ます。

compareFunction が与えられた場合、配列の要素は比較関数の返り値に基づきソートされます。もし ab が比較されようとしている要素の場合、

  • compareFunction(a, b) が 0 未満の場合、ab より小さい添字にソートします。
  • compareFunction(a, b) が 0 を返す場合、ab は互いに関して変えることなく、他のすべての要素に関してソートします。注意: ECMAScript 標準はこの振る舞いを保証しておらず、そのため一部のブラウザ (例えば、遅くとも 2003 年以前のバージョンの Mozilla) はこれを尊重していません。
  • compareFunction(a, b) が 0 より大きい場合、ba より小さい添字にソートします。

よって、比較関数は以下のような形式をもちます。

function compare(a, b) {
  if (ある順序の基準において a が b より小)
     return -1;
  if (その順序の基準において a が b より大)
     return 1;
  // a は b と等しいはず
  return 0;
}

文字列の代わりに数字を比較する場合、比較関数は単純に a から b を引けばよいでしょう。

function compareNumbers(a, b) {
  return a - b;
}

一部の JavaScript の実装では、ab が等しい場合にそれらの添字の部分的な順序を変えない安定ソートが実装されています。もしソートする前の時点で a の添字が b のより小さいなら、ソートによって ab がどう移動しようとも、ソートした後もそのままになるのです。

SpiderMonkeyGecko 1.9 以降のすべての Mozilla ベースのブラウザでは、ソートは安定ソートになっています (バグ 224128 を参照)。

sort メソッドの振る舞いは JavaScript 1.1 と JavaScript 1.2 の間で変化しました。

JavaScript 1.1 では、一部のプラットフォームで sort は動作しません。このメソッドは JavaScript 1.2 からすべてのプラットフォームで動作します。

JavaScript 1.2 では、このメソッドはもう undefined な要素を null に変換せず、代わりにそれらを配列の最後尾にソートします。例えば、このようなスクリプトがあるとします。

var a = [];
a[0] = "Ant";
a[5] = "Zebra";

// print 関数が定義されているとして
function writeArray(x) {
  for (i = 0; i < x.length; i++)   {
    print(x[i]);
    if (i < x.length-1)
      print(", ");
  }
}

writeArray(a);
a.sort();
print("\n");
writeArray(a);

JavaScript 1.1 では、JavaScript は以下のように出力します。

ant, null, null, null, null, zebra
ant, null, null, null, null, zebra

JavaScript 1.2 では、JavaScript は以下のように出力します。

ant, undefined, undefined, undefined, undefined, zebra
ant, zebra, undefined, undefined, undefined, undefined

例: 配列を生成し、表示し、ソートする

以下の例は 4 つの配列を生成し、元の配列を表示したのちに、ソートした配列を表示します。数値の配列は比較関数なしでソートされたのち、比較関数ありでソートされます。

var stringArray = ["Blue", "Humpback", "Beluga"];
var numericStringArray = ["80", "9", "700"];
var numberArray = [40, 1, 5, 200];
var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];

function compareNumbers(a, b) {
  return a - b;
}

// 再び、print 関数が定義されているとして
print("stringArray: " + stringArray.join() +"\n");
print("ソート結果: " + stringArray.sort() +"\n\n");

print("numberArray: " + numberArray.join() +"\n");
print("比較関数なしのソート結果: " + numberArray.sort() +"\n");
print("compareNumbers でのソート結果: " + numberArray.sort(compareNumbers) +"\n\n");

print("numericStringArray: " + numericStringArray.join() +"\n");
print("比較関数なしのソート結果: " + numericStringArray.sort() +"\n");
print("compareNumbers でのソート結果: " + numericStringArray.sort(compareNumbers) +"\n\n");

print("mixedNumericArray: " + mixedNumericArray.join() +"\n");
print("比較関数なしのソート結果: " + mixedNumericArray.sort() +"\n");
print("compareNumbers でのソート結果: " + mixedNumericArray.sort(compareNumbers) +"\n\n");

この例は以下のような出力をもたらします。出力結果が示すように、比較関数が使われた場合、数値はそれが数値か数字の文字列かにかかわらず正しくソートされます。

stringArray: Blue,Humpback,Beluga
ソート結果: Beluga,Blue,Humpback

numberArray: 40,1,5,200
比較関数なしのソート結果: 1,200,40,5
compareNumbers でのソート結果: 1,5,40,200

numericStringArray: 80,9,700
比較関数なしのソート結果: 700,80,9
compareNumbers でのソート結果: 9,80,700

mixedNumericArray: 80,9,700,40,1,5,200
比較関数なしのソート結果: 1,200,40,5,700,80,9
compareNumbers でのソート結果: 1,5,9,40,80,200,700

Example: Sorting maps

The compareFunction can be invoked multiple times per element within the array. Depending on the compareFunction's nature, this may yield a high overhead. The more work a compareFunction does and the more elements there are to sort, the wiser it may be to consider using a map for sorting. The idea is to walk the array once to extract the actual values used for sorting into a temporary array, sort the temporary array and then walk the temporary array to bring the original array into the right order.

// the array to be sorted
var list = ["Delta", "alpha", "CHARLIE", "bravo"];
// temporary holder of position and sort-value
var map = [];
// container for the resulting order
var result = [];

// walk original array to map values and positions
for (var i=0, length = list.length; i < length; i++) {
  map.push({    
    // remember the index within the original array
    index: i, 
    // evaluate the value to sort
    value: list[i].toLowerCase()
  });
}

// sorting the map containing the reduced values
map.sort(function(a, b) {
  return a.value > b.value ? 1 : -1;
});

// copy values in right order
for (var i=0, length = map.length; i < length; i++) {
  result.push(list[map[i].index]);
}

// print sorted list
print(result);

関連情報

ドキュメントのタグと貢献者

タグ: 
Contributors to this page: teoli, ethertank, Fajrovulpo, Mgjbot, Yuichirou
最終更新者: teoli,
サイドバーを隠す