LoginSignup
10
6

More than 5 years have passed since last update.

ワンライナーでリストとリストの突合せを行う方法

Last updated at Posted at 2017-06-11

走れメロス?

メロス(後輩)は激怒した。
かの邪智暴虐な王(常駐先のエンジニア)を除かなければならぬと決意した。

後輩はフロントエンジニアなのだが、
どうやら、バックエンド側のエンジニアが、今からコードを改修するのが面倒くさいらしく、
バックエンド側で持っているデータを、わざわざフロント側でゴニョゴニョして、
生成しなければならなくなったそうです。

詳細を聞くと

どうやら
「listAとlistBがあって、ダブっているものがあったら、listAに何か目印を追加してほしい」
というのが、今回の要件でした。

仮にこんな感じのデータがあったと想定してみます。
※「一郎」「三郎」「四郎」をダブらせています。

let listA = [
    {id:1, name:"一郎"},
    {id:2, name:"二郎"},
    {id:3, name:"三郎"},
    {id:4, name:"四郎"},
    {id:5, name:"五郎"}
];

let listB = [
    {id:4, name:"四郎"},
    {id:7, name:"七郎"},
    {id:9, name:"九郎"},
    {id:3, name:"三郎"},
    {id:1, name:"一郎"}
];

ループ中のループ

後輩は、ループの入れ子で実装したらしく、ループが無駄にならないように、きちんとbreakしたとのこと。

おそらく、こんな感じでしょうか。

sample1.js
for(let i=0; i<listA.length; i++){
    listA[i].flag = false;
    for(let j=0; j<listB.length; j++){
        if(listA[i].id == listB[j].id){
            listA[i].flag = true;
            break;
        }
    }
}

確かに、実装はできています。
でもいろいろと、改良の余地がありそうですね。

mapで書いてみる

さらに詳しく聞いてみると、
「これだとループ中にループがあってイケてないから、mapで書き直して」
と言われたそうです。

もし私が、実装するとしたら、以下のような感じでしょうか。

sample2.js
listA = listA.map(a => ({id:a.id, name:a.name, flag:listB.some(b=>b.id==a.id)}));

リスト表示用の関数

さっそく、改良前と改良後で結果が同じかどうか、JSON形式で画面に出力してみました。
関数の定義は以下の通り。

function Display(list){
    let result = JSON.stringify(list, undefined, 4);
    result = result.replace(/\n/g, "<br>").replace(/\s/g, "&nbsp;");
    document.write(result);
}

この関数は、連想配列を受け取ってJSON文字列に変換します。
そして、JSON文字列をHTMLで表示するために、改行と半角スペースを置換しています。

それでは

実際に表示させてみます。

sample2.js
listA = listA.map(a => ({id:a.id, name:a.name, flag:listB.some(b=>b.id==a.id)}));
Display(listA);
sample.html
[
    {
        "id": 1,
        "name": "一郎",
        "flag": true
    },
    {
        "id": 2,
        "name": "二郎",
        "flag": false
    },
    {
        "id": 3,
        "name": "三郎",
        "flag": true
    },
    {
        "id": 4,
        "name": "四郎",
        "flag": true
    },
    {
        "id": 5,
        "name": "五郎",
        "flag": false
    }
]

うん!ちゃんとできてますね!

まとめ

mapは便利ですね~。
私はC#の経験が一番長いのですが、Linqとよく似ています。
アロー演算子はゴーズトゥ演算子と同じですし、someはanyと同じですし。

今回は以下の記事を大いに参考にさせていただきました。
JavaScriptでforEach, filter, map, reduceとか

この調子で、実務で使用するJavaScriptでも、無駄なループが減らしながら、
見やすいコードを書いていきたいですね (^_^;

10
6
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
10
6