配列・二次配列・連想配列のソート

佐野

佐野 2014年4月9日

最近、連想配列も慣れてきて、バリバリ使っています。
最初は文字で参照している分、
通常の配列に比べ、気持ち悪い感じはしていたのですが、
文字列だけで配列に入れた要素を呼び出せるし、
慣れると便利なものです。

そして最近になって、配列をソートする事が必要になってきました。
ソートするといえば「sort()」関数で、これがなかなかの難物でした。

普通に使うと「ary.sort()」と使うのでしょうが、
これだと、アルファベット順に並ぶだけで、数値だけでは微動だにしません。
しかもこれは、戻り値で返されるのではなく、
対象の配列そのものが書き換わります。

数値でソートしたい場合は、
引数の中に関数を設置する必要があるようなのです。
その例がこちら。

var ary = [100,120,80,110,180];
ary.sort(function(a,b){
  if(a < b){return 1;}
  if(a > b){return -1;}
  return 0;
});

これで配列「ary」の中身は、「[180, 120, 110, 100, 80]」となります。

これを逆にする場合は、戻り値である「return」の値の
「1」と「-1」を逆にすればいいのですが、
正直、その仕組みもよくわかりません。
ともかく、「1」と「-1」だけ逆転すれば、順序も逆転するのです。
実は、「1」や「-1」でなくても、
正か負の値かで判断されているのらしいのですが・・・

結局、戻り値が「1」か「-1」であるのならば、
直接それを「sort()」関数の引数に入れればいいのではないかと
思うのですが、どうも、そうはいかないようなのです。
なぜか「function」でなければいけないようなのです。

細かい事はともかく、これも慣れてしまえば、割と便利かもしれません。
次に、二次配列のソートなのですが、
これも2層目の配列部分に応じてソートする事が可能です。
その例がこちら。

var ary = [
  ["いちご",100],
  ["りんご",120],
  ["みかん",80],
  ["なし",110],
  ["もも",180]
];
ary.sort(function(a,b){
  var aa = a[1];
  var bb = b[1];
  if(aa < bb){return 1;}
  if(aa > bb){return -1;}
  return 0;
});

これの場合だと、配列の2層目の
「[1]」の中身である数値に応じてソートしており、
「[0]」の部分に入ったフルーツの名前の順番は、
「もも」「りんご」「なし」「いちご」「みかん」の順に並びます。

正直、これも細かい事はよくわかりませんが、
「var aa = a[1];」「var bb = b[1];」の、「[1]」の部分を、
2層目の配列の番号に入れ替えれば、その部分を基にソートできます。

本当に、正直言うと、自分自身、
仕組みがわからないまま手を付けるのが嫌いな性分ではあるのですが、
こればかりは、やはり細かい事はわからずに、
とりあえず、どこをどういじればソートは行われるのかは、
わかった気がします。

次に難題だったのが、連想配列のソートです。
連想配列といえば、このようなものですが・・・

var ary = {
  "いちご":100,
  "りんご":120,
  "みかん":80,
  "なし":110,
  "もも":180
};

左側の文字列が、「プロパティ(属性)」という、
配列を参照するための値です。
右側が、そのプロパティで参照したときに排出される値です。

こう見てみれば、先ほどの二次配列よりもシンプルで、
より直観的に値を引き出せるように思えるのですが、
じつは、これをこのままソートする事はできません。

「javascript 連想配列 ソート」などで検索すれば、
あたかも連想配列も検索できるかのように、情報が出てきますが、
ソートが可能な連想配列にも、条件があります。

その配列というのが、以下のとおりです。

var ary = [
  {"名前":"いちご","価格":100},
  {"名前":"りんご","価格":120},
  {"名前":"みかん","価格":80},
  {"名前":"なし","価格":110},
  {"名前":"もも","価格":180}
 ];

1層目は、通常の配列となっており、
2層目からは、連想配列が入っています。
つまり、純粋な連想配列ではなく
配列の中に入った連想配列である必要があります。
そこから、同一のプロパティを条件に、ソートをかけていくという仕組みです。

これをソートした例が、以下のとおりです。

var ary = [
  {"名前":"いちご","価格":100},
  {"名前":"りんご","価格":120},
  {"名前":"みかん","価格":80},
  {"名前":"なし","価格":110},
  {"名前":"もも","価格":180}
];
ary.sort(function(a,b){
  var aa = a["価格"];
  var bb = b["価格"];
  if(aa < bb){return 1;}
  if(aa > bb){return -1;}
  return 0;
});

このコードのままソートを行えば、価格の高いものから上に並びます。
ていうか、今までの数値は、価格だったのですね。
もっとも、この金額の設定もデタラメであり、
実際に販売されている価格とは、大きく異なっているでしょうし、
消費税も8%と、中途半端に増税されたせいか、
より端数が出やすくなってたりもするでしょうが。
10%になるよりかは、まだマシとは言えなくもありませんが。

ともかく、この連想配列のソートに関しては、
けっこう苦戦したのは確かです。
やはり、ここまで来てソートの仕組みそのものは、
まだハッキリとはしていないものの、
どこをどうすれば、ソートが可能かは、わかってきたので、
もしみなさんも、そうであるならば、
忘れないうちに、独自にカスタマイズした関数として
作っておくのがいいでしょう。