コーディングの勉強

JavaScriptのsortを内部構造の踏まえてわかりやすく解説

こんにちは、mito(@mito_works)です。

mito
mito
こんにちは、久々のJavaScriptの投稿です。
momo
momo
今回はsortについてわかりやすく解説していくよ!

私自身sort関数を使う際に出てくるa,bやreturnの条件が毎回「どういう意味だっけ??」となるのでわかりやすく図解も含めて解説していきます。

それではいってみましょう~。

やりたいことの概要

javascriptで数値配列の要素を降順や昇順に並び替えたい

mito
mito
エクセルで例えると、リストデータを昇順にしたり降順にして見え方を変えるイメージです。

使用するJavaScriptの組み込みオブジェクト

Array.prototype.sort()

このまま引数なしで以下のようにソートすると昇順に並びます。

const originalAry = [2, 8, 3, 100, 70];
originalAry.sort();
console.log("originalAry引数なし", originalAry);
// 結果:2,3,8,70,100

 

mito
mito
引数なしだと、昇順にしか並ばないため、降順にしたいや要素が文字の場合文字数で並び替えたいといった場合の並び替え方法を見ていきます。

sortの引数に関数を持たせる

sortは引数に関数を持たせることができます。

momo
momo
このようなsortのようなオブジェクトを高階関数と呼ぶよ!
mito
mito
map、filter、reduceなどの組み込みオブジェクトが同じ仲間です!
const originalAry = [2, 8, 3, 100, 7];
originalAry.sort((a, b) => {
  //昇順に並べたいとき
  if (a - b < 0) {
    return -1;
  } else if (a - b == 0) {
    return 0;
  } else if (a - b > 0) {
    return 1;
  }
});
console.log("originalAry", originalAry);
//結果:2,3,7,8,100

 

momo
momo
sortの引数の中はアロー関数で記載しています。またいきなりアロー関数にaとbという引数がでてきてびっくりしたと思うのでまずはここから解説していくよ!
符号意味
 > 0aをbの後に並べる
< 0aをbの前に並べる
=== 0aとbの元の順番を維持する

参考:MDN webDocs Array.prototype.sort()

つまり、昇順に並べたい場合は、aからb減算し、マイナスであれば、前に並べたいので-1を返し、プラスであれば、aはbより大きいということになり、bの後ろに並べたいので1を返します。

momo
momo
文字だけだとわかりずらいと思うので、図を使って解説していくよ!

sortでは実際何が行われているのか?(図解)

次は、コンソールに出した結果を図解しながら解説します。

originalAry.sort((a, b) => {
  //昇順に並べたいとき
  console.log("比較開始ーーー");
  console.log("a", a);
  console.log("b", b);
  console.log(a - b);
  console.log("比較終了ーーー");
  if (a - b < 0) {
    return -1;
  } else if (a - b == 0) {
    return 0;
  } else if (a - b > 0) {
    return 1;
  }
});
console.log("originalAry", originalAry);
//結果:2,3,8,70,100

 

つまり 、、、

というような順番で並び換えが行われているようでした。

降順に並び替えてみる

momo
momo
もし、降順に並べかえたい場合hどうなるかな?
const originalAry = [2, 8, 3, 100, 7];
originalAry.sort((a, b) => {
  //降順に並べたいとき
  console.log("比較開始ーーー");
  console.log("a", a);
  console.log("b", b);
  console.log(a - b);
  console.log("比較終了ーーー");
  if (a - b < 0) {
    return 1;
  } else if (a - b == 0) {
    return 0;
  } else if (a - b > 0) {
    return -1;
  }
});
console.log("originalAry", originalAry);
//結果:100,8,7,3,2

 

mito
mito
retunの値を入れ替えればOKです。

もっと簡潔に書く

昇順の場合

マイナスを返すとaをbの前に置く

ということなので、

originalAry.sort((a, b) => {
  //昇順の場合
  return a - b;
});
console.log("originalAry", originalAry);
//結果:2,3,4,8,100

 

降順

プラスを返すとaをbの後ろに置く

ということなので、

originalAry.sort((a, b) => {
  //降順の場合
  return b - a;
});
console.log("originalAry", originalAry);
//結果:100,8,7,3,2

 

図解してみると、

 

おまけ

const items = [
  { name: "banana", cost: 100 },
  { name: "suger", cost: 580 },
  { name: "chocolate", cost: 450 },
  { name: "milk", cost: 125 },
  { name: "egg", cost: 250 },
];

items.sort((a, b) => {
  let costA = a.cost;
  let costB = b.cost;
  return costB - costA;
});

console.log("値段の降順", items);
ABOUT ME
mito
こんにちは!mitoです。 フロントエンド開発、デザイン全般をやっているクリエイターです。 学ぶことと教えることが好きです。 子育てをする中で、自分の生活に働き方を合わせたいと思うようになり、2020年4月からフリーランスになりました。 好奇心旺盛でやりたいこと多め、ワクワクすると止まれない性格です。 同じように一緒にチャレンジする人の背中そっと押せたり、励ましあえるようなブログになるといいなと思っています。