[Javascript] 複数グループの配列データを特殊な順番で並び替える方法

とある会社でマーケティング用のwebページシステムを作っていた時に、別ページへのリンク一覧を表示するシステムが必要になりました。 その会社の関連ページへの遷移になるのですが、そのリストの並び順が非常に特殊だったので、該当する関数を作って対応したので、ブログに関数を残しておきます。

具体的な仕様

グループ分けされた配列データをリスト表示する時に、指定された1つのグループをメイングループとして、リスト上部に表示する。 ただし、先頭のメイングループ2個表示したら、次に1個は別のグループ表示をする。 要するに、次のような表示になる予定です。
メイングループ
メイングループ
他のグループ
メイングループ
メイングループ
他のグループ
...

ソースコード

基本関数 : multi_sort.js

function MultiSort(datas=[] , target_group='' , target_count=0 , other_count=0){ if(!datas || !datas.length || !target_group || !target_count || !other_count){return datas} const targets = datas.filter(e => e.group === target_group) const others = datas.filter(e => e.group !== target_group) const surplus = target_count + other_count const new_datas = [] for(let i=0; i<datas.length; i++){ const delimiter = ~~(i / surplus) // main-target if(i % surplus < target_count){ if(targets.length){ new_datas.push(targets.shift()) } else if(others.length){ new_datas.push(others.shift()) } } // other else{ if(others.length){ new_datas.push(others.shift()) } else if(targets.length){ new_datas.push(targets.shift()) } } } return new_datas }

実行サンプルコード

sample.html

<script src='multi_sort.js'></script> <ol class='lists'></ol> <script> window.sample_datas = [ { "group" : "a", "name" : "name-1" }, { "group" : "b", "name" : "name-2" }, { "group" : "c", "name" : "name-3" }, { "group" : "a", "name" : "name-4" }, { "group" : "b", "name" : "name-5" }, { "group" : "c", "name" : "name-6" }, { "group" : "a", "name" : "name-7" }, { "group" : "b", "name" : "name-8" }, { "group" : "c", "name" : "name-9" }, { "group" : "a", "name" : "name-10" } ]</script> <script> const datas = MultiSort(window.sample_datas, 'b' , 2 , 1) const root = document.querySelector('.lists') for(const data of datas){ const li = document.createElement('li') li.textContent = `${data.group} : ${data.name}` li.setAttribute('data-group' , data.group) root.appendChild(li) } </script> <style> .lists li{ padding:10px; background-color:#eee; } .lists li[data-group='b']{ background-color:#FEE; } </style>

実行結果

解説

MultiSort()関数

関数実行仕様 : MultiSort(配列データ , メイングループ名 , メイングループ連続表示数 , 他のグループの連続表示数) filterを使って、配列データをメイングループと他のグループの2つの配列に分割。 surplus変数に、メインデータの連続数 + 他のグループの連速数という、ひとかたまりのグループ数を取得。 大元のメインデータを使ってfor文処理。 i % surplus < target_count の箇所は、メイングループの順番を判定しています。 それぞれのグループの時に、2つに分けた配列から、shift()にて、配列の先頭を取得して、それを新たな配列にpushしています。 この時、配列のshift()を実行すると、これは破壊的関数なので、実際のデータから先頭データは削除されています。 最後に、pushして出来上がった新しい配列をreturnで返せば完了です。

sample.html

このサンプルでは、内部でjsonからstyleの書き込みまで全て行っていますが、外部ファイルにして、読み込む形式にしても問題なく動作できます。 ただし、jsonデータをjavascriptで読み込む場合は、ajax処理が必要になるので、下記のページを参考にしてください。 [Javascript] カンタンAjaxコード