1
0

JSのMapオブジェクト グループ分けに使えそう。

Last updated at Posted at 2024-09-08

はじめに

Mapオブジェクトを使ったことない人が、これ使えるかもと思える記事です。
詳細には説明しません。
グループ分けだけを見たい人はこちら

Mapオブジェクト

連想配列を管理するオブジェクトです。
下記のように使います。これ便利だろうか?よくわからん。


const team = new Map([
    ['name', 'Falcon'],
    ['member', ['Han', 'Chewie', 'Luke']],
]);

console.log(team);
// Map(2) { 'name' => 'Falcon', 'member' => [ 'Han', 'Chewie', 'Luke' ] }

// キーを指定して取得
console.log(team.get('name'));  // "Falcon"

// キーを指定して追加
team.get('member').push('Leia');
console.log(team.get('member'));  //  ['Han', 'Chewie', 'Luke', 'Leia']

// サイズの取得
console.log(team.size);  // 2

// 新規のキーとバリューの組み合わせ(エントリー)を追加
team.has('droid') || team.set('droid', ["C-3PO", "R2-D2"]);
console.log(team.get('droid'));  // ['C-3PO', 'R2-D2']

console.log(team);
// Map(3) {
//     'name' => 'Falcon',
//     'member' => [ 'Han', 'Chewie', 'Luke', 'Leia' ],
//     'droid' => [ 'C-3PO', 'R2-D2' ]
// }

オブジェクトリテラルでもやってみる

ほぼ同じことができます。
この場合はサイズが取れません。

const team = {
    name: "Falcon",
    member: ['Han', 'Chewie', 'Luke'] ,
};

console.log(team['name']); // Falcon

team.member.push('Leia');
console.log(team.member); // [ 'Han', 'Chewie', 'Luke', 'Leia' ]

if (!team.hasOwnProperty('droid')) {
    team.droid = ["C-3PO", "R2-D2 "];
}
console.log(team.droid); // [ 'C-3PO', 'R2-D2 ' ]

console.log(team);
// {
//     name: 'Falcon',
//     member: [ 'Han', 'Chewie', 'Luke', 'Leia' ],
//     droid: [ 'C-3PO', 'R2-D2 ' ]
// }

Mapオブジェクトのキーについて

任意の型をキーにすることができ、Nanやundefindも用いることができる。

Mapオブジェクトを使ってグループ分け

次のようなオブジェクトの配列があったとします。
FalconのメンバーとそれぞれがcombatActionをもっています。
combatActionは戦闘時の動作をファンクションとして定義したプロパティです。

const Falcon = [
    { name: "Han", combatAction: pilot},
    { name: "Chewie", combatAction: support},
    { name: "Luke", combatAction: fight},
    { name: "Leia", combatAction: fight},
    { name: "R2-D2", combatAction: support},
    { name: "C-3PO", combatAction: quiet},
]

function pilot() {
    console.log('pilot');
}

function fight() {
    console.log('fight');
}

function support() {
    console.log('support');
}

function quiet() {
    console.log('');
}

combatActionが同じメンバーでグループを作るとします。
こんな感じにメンバーが分かれてくれると嬉しいです。

// 期待する結果
[
  [ { name: 'Han', combatAction: [Function: pilot] } ],
  [
    { name: 'Chewie', combatAction: [Function: support] },
    { name: 'R2-D2', combatAction: [Function: support] }
  ],
  [
    { name: 'Luke', combatAction: [Function: fight] },
    { name: 'Leia', combatAction: [Function: fight] }
  ],
  [ { name: 'C-3PO', combatAction: [Function: quiet] } ]
]

こういうときにMapオブジェクトを使うと便利です。

const Falcon = [
    { name: "Han", combatAction: pilot},
    { name: "Chewie", combatAction: support},
    { name: "Luke", combatAction: fight},
    { name: "Leia", combatAction: fight},
    { name: "R2-D2", combatAction: support},
    { name: "C-3PO", combatAction: quiet},
]

function pilot() {
    console.log('pilot');
}

function fight() {
    console.log('fight');
}

function support() {
    console.log('support');
}

function quiet() {
    console.log('');
}


const group = new Map();

Falcon.forEach(member => {
    const combatAction = member.combatAction

    // ファンクションをキーにして連想配列を作成する
    if (group.has(combatAction)) {
        group.get(combatAction).push(member);
    } else {
        group.set(combatAction, [member]);
    }
});

console.log(group);
// Map(4) {
//     [Function: pilot] => [ { name: 'Han', combatAction: [Function: pilot] } ],
//     [Function: support] => [
//         { name: 'Chewie', combatAction: [Function: support] },
//         { name: 'R2-D2', combatAction: [Function: support] }
//     ],
//     [Function: fight] => [
//         { name: 'Luke', combatAction: [Function: fight] },
//         { name: 'Leia', combatAction: [Function: fight] }
//     ],
//     [Function: quiet] => [ { name: 'C-3PO', combatAction: [Function: quiet] } ]
// }

// バリューだけのオブジェクトの配列に変換する
console.log(Array.from(group.values()));// 上記の期待する結果

// おまけ キーだけにしたりもできる
console.log(Array.from(group.keys()));
// [
//     [Function: pilot],
//     [Function: support],
//     [Function: fight],
//     [Function: quiet]
// ]

まとめ

キー・バリューの扱いがしやすくバリューのみの配列にできるところが気に入っています。
今回はファンクションをキーにしました。Mapだとこういうこともできるんですね。
実際には文字列や数値をキーにする方が多そうです。

間違いや不明点等あればご指摘ください。

参考文献

改訂3版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで 山田祥寛 著

1
0
4

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
1
0