【JavaScript】連想配列の要素をソートして並び替えてみる

javascript

久しぶりにjQueryを業務で弄っています。で、リストの一覧をアルファベット順に要素の並び替るプログラムをjQueryとJavaScriptでやってみました。

どのように要素を並び替えるか

今回は、リストの並び替えなので例えばブランドリストがあってその各ブランドごとのトップスなどのサブカテゴリーがあるようなイメージです。
そのブランド名をアルファベット順に並び替えるという感じです。下記にhtmlのソースを載せておきます。
ただ注意点としてあくまで下記のようなhtmlで組んだ場合なので参考程度にしてもらいこういう方法もあるんだ程度で呼んでもらえると助かります。

//ブランドリスト
  • Reebok
    • Reebokのサブカテゴリー
    • Reebokのサブカテゴリー
    • Reebokのサブカテゴリー
  • AMERICANRAGCIE
    • AMERICANRAGCIEのサブカテゴリー
    • AMERICANRAGCIEのサブカテゴリー
    • AMERICANRAGCIEのサブカテゴリー
  • NIKE
    • NIKEのサブカテゴリー
    • NIKEのサブカテゴリー
    • NIKEのサブカテゴリー
  • BEAMS
    • BEAMSのサブカテゴリー
    • BEAMSのサブカテゴリー
    • BEAMSのサブカテゴリー

上記の様なhtmlがあって見ていただくと判ると思うが、ブランド名だけならJavaScriptで要素を並び替えるのは簡単なんですが、サブカテゴリーがあるとちょっとひと手間加えないといけません。
ではどうやってサブカテゴリーも一緒に並び替えればいいのか試してみたところ

  • ループ処理でliタグごとに「ブランド名とhtmlソースを取得してオブジェクトにして配列を作成
  • JavaScriptのsort()の比較関数を利用して配列を並び替え
  • 並び替えた配列をhtmlとして出力する

といった流れでいきたいと思います。

htmlソースの説明

まず並び替えるにあたって各liタグごとの「ブランド名」が必要になってきますのでブラント名のliタグにクラス名「brand」を設定してブランド名をテキスト要素と取得する必要があるのでspanタグで囲っています。
ちなみに上記のhtmlのサブカテゴリーのsubクラスに関してはCSSで装飾する為のクラスです。

	
  • Reebok
  • JavaScriptのソースコード

    さて、ここから本題であるJQueryとJavaScriptを利用して要素の並び替えをしたいと思います。
    今回はボタンをクリックしたら要素を並び替えるという処理をしました。

    var brand_arr = []; //要素をいれる配列
    
    $("button").bind("click", function() {
      $("li.brand").each(function(i) {
    
        //ブランドごとに連想配列にして配列に追加
        brand_arr[i] = {
          name: $(this).find("span").text(),
          source: $(this).html()
        };
    
      });
    
      //配列を並び替え
      brand_arr.sort(
        function(a, b) {
          var a_name = a.name;
          var b_name = b.name;
          if (a_name < b_name) return -1;
          if (a_name > b_name) return 1;
          return 0;
        });
    	
      //配列を出力する
      for (var j = 0; j < brand_arr.length; j++) {
        $("li.brand").eq(j).html(brand_arr[j].source);
      }
    });
    
    

    ループ処理でliタグごとにブランド名とhtmlソースを取得する

    ループ処理や要素を取得するのはjQueryで処理しますが、まず要素を並び替えるには配列にする必要があるので各liタグごとのループ処理でブランド名とhtmlソースを取得します。

    var brand_arr = []; //要素をいれる配列
    $("li.brand").each(function(i) {
    
        //ブランドごとに連想配列にして配列に追加
        brand_arr[i] = {
          name: $(this).find("span").text(),
          source: $(this).html()
        };
    
      });
    

    htmlソースはjQeuryのhtml()で取得できます。取得する範囲はbrandクラスのliタグの中身全部です。span開始タグからサブカテゴリーのulの終了タグまでの要素を全部htmlソースとして取得しておきます。
    また、配列を並び替えるにはブランド名のアルファベットをテキスト要素として比較する必要があるのでspanタグの中身をjQueryのtext()で取得しています。

    連想配列として配列に追加する

    また、配列に追加する際にはブランド名を「name」とし取得したhtmlソースを「source」とした連想配列にしてliタグごとのワンセットにしました。

    理由は、並び替えた後にhtmlで要素を出力しますが、セットにしておかないとブランド名だけ並び替えられてサブカテゴリーの並び替えられない出力した後にブランド名とサブカテゴリーが一致しないことになってしまうからです。

    JavaScriptのsort()の比較関数を利用して配列を並び替える

    配列を並び替えるにはJavascriptのsort()を使用します。ただ通常の配列であればsortを使えばアルファベット順に要素を並び替えてくれますが、今回は配列の中身が連想配列の為ブランド名を比較するためにはsort関数に比較条件を設定した無名関数を引数で渡すことでができるのでそれで処理します。
    いわゆる比較関数と呼ばれるものですが、例えば日本語順に並び替えたい・・など通常のsort()では出来ない場合に比較関数と使うといいですが説明が長くなるのでネットで検索してみてください。

    並び替えた配列をhtmlとして出力する

    JavaScriptのsort()を使って並び替えが終わると、連想配列のnameを基準にアルファベット順に並び変わってると思いますので、その順番でjQueryのhtml()で出力します。その際は連想配列のsourceを出力すればブランド名とサブカテゴリーもhtmlソースで出力されます。

    //配列を出力する
    for (var j = 0; j < brand_arr.length; j++) { 
    	$("li.brand").eq(j).html(brand_arr[j].source);
    }
    

    まとめ

    今回はJavaScriptのsort()を使いましたがjQueryにもありますので、そちらも試されるといいかもです。sort()はいろいろ比較関数があるので、並び替えるときに知っておくと便利ですね。