JavaScript配列をユニークに(オブジェクトキーで)
lodashの _.keyBy を使うと「オブジェクト配列の重複を特定のキーでまとめて、ユニーク化」できます。プリミティブ値なら Set で十分ですが、オブジェクトは「参照が違うけど内容が同じ」というケースがあるので、キーを基準にユニーク化するのが定番です。
構文と考え方
// lodashを利用
const uniqueArr = Object.values(_.keyBy(arr, 'id'));
JavaScript_.keyBy(arr, 'id'): 配列を「id」をキーにしたオブジェクトに変換。- 同じidが複数ある場合、最後に出てきた要素で上書きされる。
Object.values(...): そのオブジェクトの値(ユニーク化された要素)を配列として取り出す。
すぐ使えるテンプレート集
基本:idでユニーク化
const arr = [
{ id: 1, name: "Pen" },
{ id: 2, name: "Note" },
{ id: 1, name: "Pencil" }, // id=1 が重複
];
const uniqueArr = Object.values(_.keyBy(arr, 'id'));
console.log(uniqueArr);
// [
// { id: 1, name: "Pencil" }, // 最後のid=1が残る
// { id: 2, name: "Note" }
// ]
JavaScript- ポイント: 同じidが複数ある場合、最後の要素で上書きされる。
別のキーでユニーク化(例:name)
const arr = [
{ id: 1, name: "Pen" },
{ id: 2, name: "Note" },
{ id: 3, name: "Pen" }, // nameが重複
];
const uniqueArr = Object.values(_.keyBy(arr, 'name'));
console.log(uniqueArr);
// [
// { id: 2, name: "Note" },
// { id: 3, name: "Pen" } // 最後の"Pen"が残る
// ]
JavaScript- ポイント: どのキーでユニーク化するかを指定できる。
複数キーを組み合わせたい場合
lodashの _.keyBy は単一キーしか指定できません。複数条件でユニーク化したい場合は、キーを文字列結合して使うことが多いです。
const arr = [
{ id: 1, type: "A", value: 10 },
{ id: 1, type: "B", value: 20 },
{ id: 1, type: "A", value: 30 }, // id+type が重複
];
const uniqueArr = Object.values(_.keyBy(arr, x => `${x.id}-${x.type}`));
console.log(uniqueArr);
// [
// { id: 1, type: "B", value: 20 },
// { id: 1, type: "A", value: 30 }
// ]
JavaScript- ポイント: 複数キーを組み合わせて「ユニークな識別子」を作る。
よくある落とし穴と対策
- 最後の要素が残る: 同じキーが複数ある場合、最後の要素で上書きされる。最初を残したいなら工夫が必要(例:reduceで最初だけ保持)。
- キーが存在しない要素:
undefinedキーにまとめられてしまう。必ずキーが存在する前提で使うか、事前にフィルタする。 - 複数条件は直接指定できない: 複数キーを組み合わせて文字列化するのが定番。
他の手段との使い分け
| 手段 | 主な用途 |
|---|---|
[...new Set(arr)] | プリミティブ値の重複除去 |
Object.values(_.keyBy(arr,'id')) | オブジェクト配列をキーでユニーク化 |
reduce | 複雑な条件でユニーク化(最初を残す/複数条件) |
Map | ネイティブでキーごとにユニーク化したい場合 |
練習問題(手を動かして覚える)
1. idでユニーク化
const arr = [
{ id: 1, name: "Pen" },
{ id: 2, name: "Note" },
{ id: 1, name: "Pencil" }
];
console.log(Object.values(_.keyBy(arr, 'id')));
// [{id:1,name:"Pencil"},{id:2,name:"Note"}]
JavaScript2. nameでユニーク化
const arr = [
{ id: 1, name: "Pen" },
{ id: 2, name: "Note" },
{ id: 3, name: "Pen" }
];
console.log(Object.values(_.keyBy(arr, 'name')));
// [{id:2,name:"Note"},{id:3,name:"Pen"}]
JavaScript3. 複数キーを組み合わせてユニーク化
const arr = [
{ id: 1, type: "A" },
{ id: 1, type: "B" },
{ id: 1, type: "A" }
];
console.log(Object.values(_.keyBy(arr, x => `${x.id}-${x.type}`)));
// [{id:1,type:"B"},{id:1,type:"A"}]
JavaScript直感的な指針
- プリミティブ値: Setでユニーク化。
- オブジェクト配列: lodashの
_.keyBy+Object.values。 - 複雑条件: reduceやMapで柔軟に。
