配列の重複した値を削除したい時のメモ。
filterでループさせindexOfで値の重複をチェックするパターン
array.indefOf(value)
がvalue自身のインデックスと異なる場合は既に配列内に同じ値があるという判定
var arr = [0, 1, 2, 3, 4.1, true, false, 1, "2", "", 4.2, null, undefined, NaN, false]; function removeDuplicateValue(arr) { return arr.filter((val, i, self) => { return self.indexOf(val) === i; }); } console.log( removeDuplicateValue1(arr) ); // => [ 0, 1, 2, 3, 4.1, true, false, '2', '', 4.2, null, undefined ]
NaN
が消えてしまう...
var a = NaN console.log( a === a ); // false
NaN
は自身を含めどの値であってもイコールにならないっぽいので、array.indexOf(NaN)
は常に-1
となり上記の方法では消えてしまう様です。
NaN
を残すようにするには最初に出てきたNaN
の時だけfilterのコールバック関数内でtrue
を返すようにすればOKでした。(しかしNaN残して使いたい場合ってあるのかな...
var arr = [0, 1, 2, 3, 4.1, true, false, 1, "2", "", 4.2, null, undefined, NaN, false, NaN]; function removeDuplicateValue(arr) { let hasNaN = false; return arr.filter((val, i, self) => { if(isNaN(val) && !hasNaN ) { hasNaN = true; return true; } return self.indexOf(val) === i; }); } console.log( removeDuplicateValue(arr) ); // => [ 0, 1, 2, 3, 4.1, true, false, '2', '', 4.2, null, undefined, NaN ]
Set (ES6) を使うパターン
Set
Set オブジェクトにより、primitive valuesでもオブジェクト参照でも、どんな型でも一意の値を格納します。
Set オブジェクトは値のコレクションです。挿入順に要素を反復することができます。Set内の値は 1度だけ発生します。その値はSetコレクション内で一意です。
[出典] Set - JavaScript | MDN
var arr = [0, 1, 2, 3, 4.1, true, false, 1, "2", "", 4.2, null, undefined, NaN, false, NaN]; var a1 = Array.from( new Set(arr) ); console.log(a1); // => [ 0, 1, 2, 3, 4.1, true, false, '2', '', 4.2, null, undefined, NaN ] var a2 = [...new Set(arr)]; console.log(a2); // => [ 0, 1, 2, 3, 4.1, true, false, '2', '', 4.2, null, undefined, NaN ]
Array.from()
Array.from() メソッドは、配列型 (array-like) オブジェクトや反復可能 (iterable) オブジェクトから新しい Array インスタンスを生成します。
[出典] Array.from() - JavaScript | MDN
new Set()
で一意の値の反復可能オブジェクトにしてArray.from()
に渡して配列化。
スプレッド演算子
...
スプレッド演算子 は、複数の引数 (関数呼び出しのため) または複数の要素 (配列リテラルのため)、あるいは複数の値 (分割代入のため) が置かれるところで式が展開されます。
[出典] スプレッド構文 - JavaScript | MDN
配列や反復可能オブジェクトを値で分割展開できる演算子のようです。(スプレッド演算子って名前初めて知りました)
配列の初期化時に反復可能オブジェクトを展開して値として渡して配列化しているようです。
EX
var arr1 = [1,2,3]; var arr2 = [4,5,6]; arr1.push(...arr2); arr1; //=> [1, 2, 3, 4, 5, 6]; var set = new Set(); set.add(1); set.add(2); set.add(3); console.log(set); // => Set { 1, 2, 3 } console.log( [...set] ); // => [ 1, 2, 3 ]
Set()
を使えば簡単に重複を削除できるのですが、Array.from
と...
含めてまだサポートしていないブラウザも有るようなのでWEBで本格的に使えるようになるのは使えるようになるのはもう少し先なのかな。と思いました。
[参考]
- 配列の重複をはじく、もしくは重複を取り出す - Qiita
- javascript - Remove duplicate values from JS array - Stack Overflow
- array.indexOf can't find NaN - Stack Overflow
- Set - JavaScript | MDN
- 反復処理プロトコル - JavaScript | MDN
- Array.from() - JavaScript | MDN
- スプレッド構文 - JavaScript | MDN
プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問
- 作者: 増井敏克
- 出版社/メーカー: 翔泳社
- 発売日: 2015/10/14
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (11件) を見る