JS 配列の重複を排除する 9 つの高度な方法 (実証済みで効果的)

JS 配列の重複を排除する 9 つの高度な方法 (実証済みで効果的)

序文

一般的な方法はここには記載されていませんが、等しいかどうかを判断するための二重ループや、比較のために新しい配列を作成してプッシュするなど、他にもたくさんあります。スプライスメソッドを使用して要素を削除すると、配列が崩壊する可能性があるため、対処する必要があることに注意してください。

この記事では、多数の高レベルメソッドとAPIを使用して、さまざまな配列重複排除方法を紹介し、対応する説明と構文を示します。他にも多くの組み合わせ呼び出し方法があります。原則的なロジックは実際には似ています。その中で、forループはforEachメソッドに変換できるため、ここでは1つずつリストしません。より良いアルゴリズムがある場合は、メッセージを残してアドバイスを求めてください。 !

配列[1,2,2,4,null,null,'3','abc',3,5,4,1,2,2,4,null,null,'3','abc',3,5,4]が与えられた場合、重複を削除します。

arr = [1,2,2,4,null,null,'3','abc',3,5,4,1,2,2,4,null,null,'3','abc',3,5,4] とします。 

1. オブジェクトの一意のキーを使用する

ご存知のとおり、オブジェクトのキーは繰り返すことができません。繰り返すと、後者が前者を上書きしてしまいます。この機能を使用すると、配列の重複を排除し、配列を走査し、配列内の各項目をオブジェクトのキー値として使用することができます。

obj = {} とします。
(i = 0 とします; i < arr.length; i++) {
 アイテムを arr[i] とします。
 if (obj[item] !== 未定義) {
 arr.splice(i, 1);
 i--; // 要素を削除した後に配列が崩壊する問題を解決します continue;
 }
 obj[item] = アイテム
}

// 引数: [1, 2, 4, null, "3", "abc", 3, 5]

2. 要素を交換してスプライス方式を置き換える

上記の方法には、一定のパフォーマンス上の問題があります。つまり、スプライスに基づく削除パフォーマンスはあまり良くありません。現在の項目が削除された後、後続の各項目のインデックスを 1 つずつ前方に移動する必要があります。データ量が多い場合、パフォーマンスに確実に影響します。

上記の考慮に基づいて、要素の位置を交換する方が効率的になります。現在の要素が重複している場合は、配列の最後の要素と交換され、i--を再度判断できます。同時に、配列の長さであるlength--を操作して配列の最後の要素を削除するため、配列内の他の要素は影響を受けません。

obj = {} とします。
(i = 0 とします; i < arr.length; i++) {
 アイテムを arr[i] とします。
 if (obj[item] !== 未定義) {
 arr[i] = arr[arr.長さ - 1]
 配列の長さ--;
 私 - ; 
 続く;
 }
 obj[item] = アイテム
}
// 引数: [1, 2, 4, null, "3", "abc", 3, 5]

3. Array.filter + Array.indexOf

filter() メソッド: 指定された配列内で特定の条件を満たすすべての要素を要素とする新しい配列を作成します。条件に一致する要素がない場合、空の配列が返されます。

構文: array.filter(function(item,index,arr))

  • filter() は空の配列を検出しません。
  • filter() は元の配列を変更しません。

原則: アイテムの最初の出現が現在のインデックスと等しい要素を返します。

newArr = arr.filter((item, index) => arr.indexOf(item) === index); とします。 

// [1, 2, 4, null, "3", "abc", 3, 5]

4. Array.filter + Object.hasOwnProperty

hasOwnProperty() メソッド: オブジェクトに指定されたプロパティがあるかどうかを示すブール値を返します。

原則: オブジェクトのキー名の非繰り返し性を利用する

obj = {} とします

arr.filter(item => obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)) 

5. Array.reduce + Array.includes

Reduce() メソッド: 関数を累積器として受け取り、配列内の各値が左から右に計算され、最終的に値として計算されます。

構文: arr.reduce(function(total, currValue, currIndex, arr), initValue)

Reduce() は空の配列に対してコールバック関数を実行しません。

合計: 必須。初期値、または計算後の戻り値

currValue: 必須。現在の要素

currIndex:オプション。現在の要素のインデックス

arr : オプション。現在の配列オブジェクト。

initValue: オプション。アキュムレータ初期値

初期値を指定せずに空の配列に対してreduce()メソッドを呼び出すと、エラーが発生します。

空の配列でreduce()メソッドを呼び出し、初期値を指定すると、コールバック関数を呼び出さずに初期値が直接返されます。

空でない配列が初期値を提供するためにreduce()を呼び出す場合、totalは初期値と等しくなり、currValueは最初の要素から始まります。初期値が指定されていない場合、totalは最初の要素の値と等しくなり、currValueは2番目の要素から始まります。

newArr = arr.reduce((accu, cur) => { とする
 return accu.includes(cur) ? accu : accu.concat(cur); // 1. 連結メソッド // return accu.includes(cur) ? accu : [...accu, cur]; // 2. 拡張操作}, []);


// [1, 2, 4, null, "3", "abc", 3, 5]

6. 配列のインデックス

indexOf() メソッド: 配列内の指定された要素の位置を返します。このメソッドは配列を走査し、対応する要素を検索し、その要素が最初に出現したインデックスを返します。指定された要素が見つからない場合は、-1 を返します。

newArr = [] とします
(var i = 0; i < arr.length; i++) の場合 {
 (newArr.indexOf(arr[i]) === -1)の場合、newArr.push(arr[i]) 
}

// forEach と同等 arr.forEach( item => newArr.indexOf(item) === -1 ? newArr.push(item) : '')

console.log(newArr) // [1, 2, 4, null, "3", "abc", 3, 5]

7. 配列.includes

include() メソッド: 配列に指定された値が含まれているかどうかを判断するために使用され、含まれている場合は true を返し、含まれていない場合は false を返します。

newArr = [] とします
(var i = 0; i < arr.length; i++) の場合 {
 newArr.includes(arr[i]) の場合、newArr.push(arr[i])
}

// forEach と同等 arr.forEach( item => !newArr.includes(item) ? newArr.push(item) : '')

console.log(newArr) // [1, 2, 4, null, "3", "abc", 3, 5]

8. 新しいセット + スプレッド演算子 || Array.from

ES6 は新しいデータ構造 Set を提供します。配列に似ていますが、メンバーの値は一意であり、重複する値はありません。

Set 自体は、初期化のために反復可能なインターフェースを持つデータ構造 (配列、文字列など) をパラメーターとして受け入れることができるコンストラクターです。

let newArr = [...new Set(arr)]; // [1, 2, 4, null, "3", "abc", 3, 5]

let newArr = Array.from(new Set(arr)); // [1, 2, 4, null, "3", "abc", 3, 5]

newStr = [...new Set('ababbc')].join('') // 'abc' とします。

9. 新しいマップ

ES6 は新しいデータ構造 Map を提供します。オブジェクトと同様に、キーと値のペアの集合体ですが、「キー」の範囲は文字列に限定されません。さまざまな型の値(オブジェクトを含む)をキーとして使用できます。

set メソッドは、キー名 key に対応するキー値を value に設定し、Map 構造全体を返します。キーにすでに値がある場合はキーの値が更新され、それ以外の場合は新しいキーが生成されます。

get メソッドは、キーに対応するキー値を読み取ります。キーが見つからない場合は、undefined を返します。

has メソッドは、キーが現在の Map オブジェクト内にあるかどうかを示すブール値を返します。

map = new Map();
newStr = [] とします。

(i = 0 とします; i < arr.length; i++) {
 もし(!map.has(arr[i])) {
  マップをセットします(arr[i], true);
  newStr.push(arr[i]);
 }
}
console.log(newArr) // [1, 2, 4, null, "3", "abc", 3, 5]

要約する

これで、JS 配列の重複排除に関する 9 つの高度な方法についての記事は終了です。より関連性の高い JS 配列の重複排除コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • js 配列から重複を削除する 11 の方法
  • JS 配列のフラット化、重複排除、ソート操作の詳細な例
  • JS配列属性の重複排除と重複データの検証
  • 高性能 js 配列重複排除 (12 種類の方法、史上最も包括的)
  • JS配列におけるオブジェクト重複排除の例
  • js配列重複排除方法の概要
  • JS 配列の重複排除の 6 つの方法と完全な例
  • js 配列から重複を削除する N 個の方法 (要約)
  • JS配列の重複排除の一般的な方法の概要[4つの方法]
  • JS配列重複排除の詳細

<<:  MySQL 5.7 解凍版のインストール、アンインストール、および文字化けしたコードの問題のグラフィック解決

>>:  Linux システムにおける時間設定の概要

推薦する

CentOS6で定期的にjarプログラムを実行するスクリプトをcrontabで実行する

1. 簡単なJavaプログラムを書く パブリッククラステストシェル{ パブリック静的voidメイン(...

デザイン理論: テキストの読みやすさと可読性

<br />少し前に、ビジネス上の必要性から、ラップトップに Souba をインストール...

iframe ページパラメータの文字化けの問題について議論

非常に珍しいパラメータ文字化けの問題に遭遇しました。まずページを見てみましょう写真に示すように、月次...

MySQL 権限昇格のさまざまな形態の概要

目次1. Webshel​​lを書く出力ファイルにシェルを書き込むログファイル書き込みシェル2. U...

mysqlは複数の主キーを設定する操作を実装します

ユーザーテーブル、ID番号は一意である必要があります、携帯電話番号、電子メールアドレスは一意である必...

MySQL 5.7.24 のインストールと設定のグラフィックチュートリアル

この記事では、MySQL 5.7.24のインストールと設定のチュートリアルを参考までに紹介します。具...

Linuxでスワップパーティションファイルを作成する方法

スワップの紹介Linux のスワップ (スワップ パーティション) は、Windows の仮想メモリ...

JS における ES6 継承と ES5 継承の違い

目次継承ES5 プロトタイプ継承ES6 クラス継承両者の違いES5プロトタイプ継承の内部実装ES6 ...

CSS 位置プロパティが絶対の場合のパーセンテージ値の計算

位置が絶対の場合、関連する属性のパーセンテージは、参照先の要素 (包含ブロック) を基準として計算さ...

Dockerfile を使用して Java ランタイム環境のミラーを作成する方法

現在の環境は次のとおりです。セントロス7.5 docker-ce 18.06.1-ce 1. まずc...

HTMLの基礎を詳しく解説(第2部)

1. リストリスト ulコンテナーには、一貫した構造とスタイルを持つテキストまたはグラフの形式が読...

PSSHを使用してLinuxサーバーを一括管理する

pssh は、多数のマシンでのバッチ ssh 操作に使用される、Python で実装されたオープン ...

タブ切り替えを実装するための HTML サンプル コード

タブ切り替えもプロジェクトではよく使われる技術です。一般的にタブ切り替えはjsやjqを使って実装され...

CSS3 で虫眼鏡効果を模倣するいくつかの方法の原理の分析

記事のタイトルが「模造虫眼鏡」なのはなぜですか?今日お話ししたいのは、一般的に言われているような、マ...

Window.nameはクロスドメインデータ転送の問題を解決します

<br />原文: http://research.microsoft.com/~hel...