4
0

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 1 year has passed since last update.

Array.prototype.sort()メソッドの使い方(備忘録)

Posted at

この投稿は

JavaScriptのsort()メソッドの使い方が分からなかったので備忘録としてのメモです。
sort()メソッドを使ったコードを見ると、みんな当たり前のように引数に関数を使っているし、戻り値の訳が分からんし・・・ってことで。

基本形

JavaScriptのsort()メソッドは、どうやら「高階関数」ってやつで、引数に関数を指定するっぽい。
MDN によると、引数として設定する関数は以下のようにaとbを引数とした、無名のアロー関数で記述するんだそうだ。(もちろん、別の書き方もあるはず。)

const array = []; //配列の宣言

array.sort((a,b) => {
    //関数の中身
});

こんな感じかな?
引数aとbは、配列から適当に「要素」を代入してくれるらしい。開発者はaとbを比較とか演算すればいいんだそうだ。

戻り値の意味

関数の戻り値が一番意味が分からなかったんだよね。サンプルのプログラムを見るとみんなこんな風に書いてある。

array.sort((a,b) => {
    return a-b;
});

なんで計算結果を返すといいんだか? 全く分からなかった。
これも、MDN に書いてあった。
戻り値で要素aとbの並びを変えるらしい。

戻り値とその挙動
戻り値 挙動 要素aとbの位置関係
0以上 a を b の後ろに並べる
並び
b
a
0以下 b を a の後ろに並べる
並び
a
b
何もしない 元と同じ

なので、戻り値が0以上の時は、並びが逆転するっぽい。
これで、数値を戻り値にする意味がわかった。

上記を踏まえて昇順ソート

上記を踏まえて、1次元配列の昇順ソートをするとなると、

const array = [4,4,2,3,2,3]; //テスト用に配列に要素を設定

array.sort((a,b) => {
  if (a == b) {
    return 0;
  } else if (a > b) {
    return 1;
  } else {
    return -1;
  }
});

のようになる。
ここで、戻すべき戻り値をもう一度見てみよう。
「0以上」「0以下」「0」となっている。
「1」「ー1」「0」ではない。
なので、昇順ソートは以下のようにも書き換えられるみたい。

const array = [4,4,2,3,2,3]; //テスト用に配列に要素を設定

array.sort((a,b) => {
  return a - b;
});

数値であればこっちの方がすっきりする。

降順ソートは?

1次元配列の降順ソートをするとなると、b より a が小さい場合0以上を戻せばいいのだから、

const array = [1,4,2,3,2,3]; //テスト用に配列に要素を設定

array.sort((a,b) => {
  if (a == b) {
    return 0;
  } else if (a > b) {
    return -1;
  } else {
    return 1;
  }
});

のようになる。また、以下のようにも書き換えられる。

const array = [1,4,2,3,2,3]; //テスト用に配列に要素を設定

array.sort((a,b) => {
  return b - a;
});

二次元配列のソート

キー1つで昇順の場合

二次元配列を1つのキーでソートする時はこう考えるとよさそう。
二次元配列を表と考えて、引数に渡される要素は「行」部分と考える、また、行の中の「列」を比較するようにする。
こんな感じ。

const array = [
  [4,2],
  [4,1],
  [2,2],
  [3,3],
  [2,2],
  [3,5]
]; //テスト用に配列に要素を設定

//aとbには、表でいう行部分([4,1]とか[2,2]とか・・・)が引き渡される。
array.sort((a,b) => {
  //表でいう列部分を比較する。
  if (a[0] == b[0]) {
    return 0;
  } else if (a[0] > b[0]) { 
    return 1;
  } else {
    return -1;
  }
});

また、以下のようにも書き換えられる。

const array = [
  [4,2],
  [4,1],
  [2,2],
  [3,3],
  [2,2],
  [3,5]
]; //テスト用に配列に要素を設定

//aとbには、表でいう行部分([4,1]とか[2,2]とか・・・)が引き渡される。
array.sort((a,b) => {
  //表でいう列部分を演算する。
  return a[0] - b[0];
});

キー2つで昇順の場合

二次元配列を2つのキーでソートする時は、
キー1が同じときだけ、キー2を比較すると良さそうだ。

const array = [
  [4,2],
  [4,1],
  [2,2],
  [3,3],
  [2,2],
  [3,5]
]; //テスト用に配列に要素を設定

//aとbには、表でいう行部分([4,1]とか[2,2]とか・・・)が引き渡される。
array.sort((a,b) => {
  //表でいう列部分(キー1)を比較する。
  if (a[0] == b[0]) {
    //キー1が同じときだけ、キー2を比較する。
    //表でいう列部分(キー2)を比較する。
    if (a[1] == b[1]) {
      //キー1とキー2が同じなら0を戻す。
      return 0;
    } else if (a[1] > b[1]) { 
      return 1;
    } else {
      return -1;
    }
  } else if (a[0] > b[0]) { 
    return 1;
  } else {
    return -1;
  }
});

また、以下のようにも書き換えられる。

const array = [
  [4,2],
  [4,1],
  [2,2],
  [3,3],
  [2,2],
  [3,5]
]; //テスト用に配列に要素を設定

//aとbには、表でいう行部分([4,1]とか[2,2]とか・・・)が引き渡される。
array.sort((a,b) => {
  //表でいう列部分(キー1)を比較する。
  if (a[0] == b[0]) {
    //キー1が同じときだけ、表でいう列部分(キー2)を演算する。
    return a[1] - b[1];
  } else {
    //表でいう列部分(キー1)を演算する。
    return a[0] - b[0];
  }
});

オブジェクトのソート

オブジェクト配列の場合は、a や b に引き渡されるものはオブジェクト( {'v1':4,'v2':4} など)。
比較はオブジェクトの値を比較すれば良さそう。

let array = [
  {'v1':3,'v2':3},
  {'v1':4,'v2':4},
  {'v1':1,'v2':3},
  {'v1':2,'v2':4},
  {'v1':1,'v2':1},
  {'v1':2,'v2':4},
]

//aやbにはオブジェクト({'v1':2,'v2':4})が引き渡される。
array.sort((a,b) => {
  //オブジェクトの値を比較。
  if (a.v1 == b.v1) {
    return 0;
  } else if (a.v1 > b.v1) {
    return 1; 
  } else {
    return -1;
  }
});

これも、次のように書き換えられる。

let array = [
  {'v1':3,'v2':3},
  {'v1':4,'v2':4},
  {'v1':1,'v2':3},
  {'v1':2,'v2':4},
  {'v1':1,'v2':1},
  {'v1':2,'v2':4},
]

//aやbにはオブジェクト({'v1':2,'v2':4})が引き渡される。
array.sort((a,b) => {
  //オブジェクトの値を比較。
  return a.v1 - b.v1; 
});

まとめ

僕なりのまとめ。

  • sort()メソッドを使うためには、引数に以下のように a と b を引数とした関数を記載。
  • その関数内で、0以上、0以下、0のいずれかを戻す。
  • 戻り値が、0以上なら、要素の並びが逆転する。
const array = []; //配列の宣言

array.sort((a,b) => {
    //関数の中身
});
4
0
0

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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?