配列内に重複した要素がある場合、同じものをマージして1つにするやり方です。
値、文字列の重複をまとめる
new Set()
を使うと、配列内に重複している値、数値などを簡単に重複を1つにまとめることができます。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set
const numbers = [1,2,54,3,4,6,3,3,54,10];
const numbersFiltered = new Set(numbers);
console.log([...numbersFiltered]) // [1, 2, 54, 3, 4, 6, 10]
new Set()
で生成したもの(ここでいうnumbersFiltered
)を出力しようとすると Set オブジェクトになってしまっているので、配列として扱いたい場合はスプレッド演算子(…)で抜き出せます。
オブジェクトの重複をまとめる
オブジェクトの重複は Set ではまとめられません。filter と findIndex を組み合わせて使うと良いみたいです。
例:data を重複フィルタリングする
const data = [ ...何かしらのオブジェクト ];
const dataFiltered = data.filter((element, index, self) => self.findIndex(
(dataElement) => dataElement.id === element.id ) === index
);
data
はオブジェクトの配列とします。このオブジェクトの中身のid
が同じものは重複と見なし、2つ目は除外する例です。
array.filter()
… true なら配列に追加するarray.findIndex()
… true ならその要素のインデックス番号を返す
filter()
は配列の中身を一つずつ取り出して、何らかの条件が true であれば、配列に追加していき、フィルタリングされた配列を返します。なので常に true を返すと、最初とまったく同じ配列が出来上がるだけで意味はありません。
findIndex()
は配列の中身を一つずつ取り出して、何らかの条件が true であれば、その要素のインデックス番号を返します。もし true にならなければ、-1
が返るというものです。
なので、上記でやっていることの流れとしては
filter()
で重複をまとめたい配列をフィルタリングfilter()
の第三引数 self (フィルタリングをしようとしてる配列が入る。例でいうとdata
)に対してfindIndex()
をかける- data に入ってる id と、
filter()
で順番に取り出している element の id が等しければ、data に入っている index 番号を返す(合致した一番最初の要素) - その index 番号が
filter()
で順番に取り出している index 番号と等しければ、最終的に返す配列に追加する
findIndex()
は合致した一番最初の要素を返すのがキモです。
例えば、配列内の 2番目、5番目、10 番目のオブジェクトの id が同じだった場合、findIndex()
は2番目のインデックス番号を返してきます。
なので、2番目 === index
となり、index が 2番目の時のみ true、新しい配列に加えられます。5番目と10番目はスルーされ、重複しているオブジェクトは一つだけになるという戦法です。
正直自分では考え付きませんでした。すごいです。。