JavaScript 配列の重複排除方法

Nov 27, 2017 am 09:24 AM
javascript js 配列

さまざまなプログラミング言語に配列の重複排除があることは誰もが知っていますが、この記事では、皆さんのお役に立つことを願って、JavaScript の配列重複排除について説明します。

二層ループ

おそらく最初に思いつくのは、indexOf を使用して判定をループすることですが、この方法の前に、まず最も独創的な方法を見てみましょう:

var array = [1, 1, '1', '1'];function unique(array) {    // res用来存储结果
    var res = [];    for (var i = 0, arrayLen = array.length; i < arrayLen; i++) {        for (var j = 0, resLen = res.length; j < resLen; j++ ) {            if (array[i] === res[j]) {                break;
            }
        }        // 如果array[i]是唯一的,那么执行完循环,j等于resLen
        if (j === resLen) {
            res.push(array[i])
        }
    }    return res;
}console.log(unique(array)); // [1, "1"]
ログイン後にコピー

この方法では、loop を使用します。ネスト、最も外側のループは array で、内側のループは res です。array[i] の値が res[j] の値と等しい場合、それらが等しくない場合は、ループから抜け出します。このとき、j の値は res と等しくなります。この特性に基づいて長さを判断し、その値を res に加算します。

なぜこの方法についてお話したいかというと、とても単純なようですが、それは————相性が良いからです。

indexOf

indexOf を使用して内部ループを簡素化できます:

var array = [1, 1, &#39;1&#39;];function unique(array) {    var res = [];    for (var i = 0, len = array.length; i < len; i++) {        var current = array[i];        if (res.indexOf(current) === -1) {
            res.push(current)
        }
    }    return res;
}console.log(unique(array));
ログイン後にコピー

ソート後の重複排除

まず、sort メソッドを使用して重複排除された配列をソートし、同じ値がまとめて配置されることを想像してください。現在の要素が前の要素と同じであるかどうかを判断することができます。同じである場合は、それを res に追加します:

var array = [1, 1, &#39;1&#39;];function unique(array) {    var res = [];    var sortedArray = array.concat().sort();    var seen;    for (var i = 0, len = sortedArray.length; i < len; i++) {        // 如果是第一个元素或者相邻的元素不相同
        if (!i || seen !== sortedArray[i]) {
            res.push(sortedArray[i])
        }
        seen = sortedArray[i];
    }    return res;
}console.log(unique(array));
ログイン後にコピー

Ifソートされた配列の重複を排除します。この方法は、indexOf を使用するより効率が確実に高くなります。

unique API

これら 2 つのメソッドを理解した後、入力された配列が重複しているかどうかを isSorted パラメーターに基づいて判断し、対応する隣接要素が重複しているかどうかを判断します。同じ、 false の場合、indexOf を使用して

var array1 = [1, 2, &#39;1&#39;, 2, 1];var array2 = [1, 1, &#39;1&#39;, 2, 2];// 第一版function unique(array, isSorted) {    var res = [];    var seen = [];    for (var i = 0, len = array.length; i < len; i++) {        var value = array[i];        if (isSorted) {            if (!i || seen !== value) {
                res.push(value)
            }
            seen = value;
        }        else if (res.indexOf(value) === -1) {
            res.push(value);
        }        
    }    return res;
}console.log(unique(array1)); // [1, 2, "1"]console.log(unique(array2, true)); // [1, "1", 2]
ログイン後にコピー

最適化

を判断します。 unqique はすでに重複排除機能を試すことができますが、この API をより強力にするために、要件を考慮してみましょう:

新しい要件: 文字 上位と下位'a' と 'A' のように、大文字と小文字は一貫しているとみなされます。1 つだけ保持してください。

すべての文字を小文字に変換するなど、最初に配列内のすべてのデータを処理してから、それを独自の関数に渡すことはできますが、配列の処理ループを省略して重複排除に直接進む方法はありますか?ループを中国でやるのはどうですか?この要件を満たしましょう:

var array3 = [1, 1, &#39;a&#39;, &#39;A&#39;, 2, 2];// 第二版// iteratee 英文释义:迭代 重复function unique(array, isSorted, iteratee) {    var res = [];    var seen = [];    for (var i = 0, len = array.length; i < len; i++) {        var value = array[i];        var computed = iteratee ? iteratee(value, i, array) : value;        if (isSorted) {            if (!i || seen !== value) {
                res.push(value)
            }
            seen = value;
        }        else if (iteratee) {            if (seen.indexOf(computed) === -1) {
                seen.push(computed);
                res.push(value);
            }
        }        else if (res.indexOf(value) === -1) {
            res.push(value);
        }        
    }    return res;
}console.log(unique(array3, false, function(item){    return typeof item == &#39;string&#39; ? item.toLowerCase() : item
})); // [1, "a", 2]
ログイン後にコピー

この実装と最後のバージョンでは、関数は 3 つのパラメーターを渡します:

array: 複製される配列を示し、必須

isSorted: 渡される関数を示します。ソートされている場合、true の場合、より高速な方法で重複排除が行われます

iteratee: 関数を渡して各要素を再計算し、処理結果に基づいて重複排除を行います

ここまで、アイデアに基づいて独自の関数を作成しました。詳細についてはGithubを確認してください。

filter

ES5 は、外側のループを簡素化するために使用できるフィルター メソッドを提供します:

たとえば、indexOf を使用するメソッド:

var array = [1, 2, 1, 1, &#39;1&#39;];function unique(array) {    var res = array.filter(function(item, index, array){        return array.indexOf(item) === index;
    })    return res;
}console.log(unique(array));
ログイン後にコピー

並べ替えと重複排除のメソッド:

var array = [1, 2, 1, 1, &#39;1&#39;];function unique(array) {    return array.concat().sort().filter(function(item, index, array){        return !index || item !== array[index - 1]
    })
}console.log(unique(array));
ログイン後にコピー

オブジェクトのキーと値のペア

重複排除の方法 多くの場合、アンダースコアに続く独自の API を既に作成しましたが、視野を広げるために他のメソッドを見てみましょう:

このメソッドは、配列の値をキーとして保存します。たとえば、Object[value1] = true の場合、別の値を判定する場合、Object[value2] が存在する場合、その値は重複していることを意味します。サンプルコードは以下の通りです。

var array = [1, 2, 1, 1, &#39;1&#39;];function unique(array) {    var obj = {};    return array.filter(function(item, index, array){        return obj.hasOwnProperty(item) ? false : (obj[item] = true)
    })
}console.log(unique(array)); // [1, 2]
ログイン後にコピー

1と'1'が異なるので問題があることが分かりますが、このメソッドでは同じ値と判断してしまうためです。したがって、この問題を回避するには、typeof item + item をキー値として使用できます。

var array = [1, 2, 1, 1, &#39;1&#39;];function unique(array) {    var obj = {};    return array.filter(function(item, index, array)
{        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
    })
}console.log(unique(array)); // [1, 2, "1"]
ログイン後にコピー

ES6

ES6 の登場により、重複排除の方法が進歩しました。 Set および Map データ構造を使用します。Set を例に挙げると、ES6 は新しいデータ構造 Set を提供します。配列に似ていますが、メンバーの値は一意であり、重複する値はありません。

体重を減らす準備をしていると感じていますか?バージョンを書いてみましょう:

var array = [1, 2, 1, 1, &#39;1&#39;];function unique(array) {   return Array.from(new Set(array));
}console.log(unique(array)); // [1, 2, "1"]
ログイン後にコピー

さらに簡略化することもできます:

function unique(array) {    return [...new Set(array)];
}
ログイン後にコピー

さらに簡略化することもできます:

var unique = (a) => [...new Set(a)]
ログイン後にコピー

さらに、Map を使用する場合:

function unique (arr) {    const seen = new Map()    return arr.filter((a) => !seen.has(a) && seen.set(a, 1))
}
ログイン後にコピー

JavaScript の進化

重複排除が確認できます。このメソッドは、元の 14 行のコードから ES6 の 1 行のコードになりました。これは実際に JavaScript 言語が常に改良されていることを示しており、今後の開発はますます効率的になるものと信じています。

特別な型の比較

重複排除の方法はここで終了します。ただし、重複排除の対象となる要素の型は、例の単純な 1 と '1' 以外にも、実際には null、未定義、NaN などさまざまです。それでは、これらの要素について、前の方法の重複排除の結果はどうなるのでしょうか?

その前に、いくつかの例を見てみましょう:

var str1 = &#39;1&#39;;var str2 = new String(&#39;1&#39;);console.log(str1 == str2);
 // trueconsole.log(str1 === str2); // falseconsole.log(null == null);
  // trueconsole.log(null === null); // trueconsole.log(undefined == undefined);
   // trueconsole.log(undefined === undefined); // trueconsole.log(NaN == NaN);
    // falseconsole.log(NaN === NaN); // falseconsole.log(/a/ == /a/); 
    // falseconsole.log(/a/ === /a/); // falseconsole.log({} == {});
     // falseconsole.log({} === {});
      // false
ログイン後にコピー

それでは、そのような配列の場合

var array = [1, 1, &#39;1&#39;, &#39;1&#39;, null, null, undefined, undefined, new String(&#39;1&#39;), new String(&#39;1&#39;), /a/, /a/, NaN, NaN];
ログイン後にコピー

上記の重複排除方法の結果はどうなるでしょうか?

特別にリストをコンパイルしました。オブジェクトと NaN の重複排除に焦点を当てています:


メソッド結果の説明


for ループ [1, "1", null, unknown, String, String , /a /, /a/, NaN, NaN] オブジェクトと NaN は重複しません

indexOf [1, "1", null, undefined, String, String, /a/, /a/, NaN, NaN] 对象和 NaN 不去重

sort [/a/, /a/, "1", 1, String, 1, String, NaN, NaN, null, undefined] 对象和 NaN 不去重 数字 1 也不去重

filter + indexOf [1, "1", null, undefined, String, String, /a/, /a/] 对象不去重 NaN 会被忽略掉

filter + sort [/a/, /a/, "1", 1, String, 1, String, NaN, NaN, null, undefined] 对象和 NaN 不去重 数字 1 不去重

优化后的键值对方法 [1, "1", null, undefined, String, /a/, NaN] 全部去重

Set [1, "1", null, undefined, String, String, /a/, /a/, NaN] 对象不去重 NaN 去重

想了解为什么会出现以上的结果,看两个 demo 便能明白:

// demo1var arr = [1, 2, NaN];
arr.indexOf(NaN); // -1

indexOf 底层还是使用 === 进行判断,因为 NaN ==== NaN的结果为 false,所以使用 indexOf 查找不到 NaN 元素

// demo2function unique(array) {   return Array.from(new Set(array));
}console.log(unique([NaN, NaN])) // [NaN]
ログイン後にコピー

Set 认为尽管 NaN === NaN 为 false,但是这两个元素是重复的。

写在最后

虽然去重的结果有所不同,但更重要的是让我们知道在合适的场景要选择合适的方法。

以上内容就是各种不同的JavaScript数组去重方法,如果大家觉得有用的话赶紧收藏起来吧。

相关推荐:

javascript数组去重/查找/插入/删除的方法

js数组去重方法汇总

JavaScript数组去重方法总结

JS实现数组去重的实例介绍

js实现数组去重的几种方法总结

以上がJavaScript 配列の重複排除方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

推奨: 優れた JS オープンソースの顔検出および認識プロジェクト 推奨: 優れた JS オープンソースの顔検出および認識プロジェクト Apr 03, 2024 am 11:55 AM

顔の検出および認識テクノロジーは、すでに比較的成熟しており、広く使用されているテクノロジーです。現在、最も広く使用されているインターネット アプリケーション言語は JS ですが、Web フロントエンドでの顔検出と認識の実装には、バックエンドの顔認識と比較して利点と欠点があります。利点としては、ネットワーク インタラクションの削減とリアルタイム認識により、ユーザーの待ち時間が大幅に短縮され、ユーザー エクスペリエンスが向上することが挙げられます。欠点としては、モデル サイズによって制限されるため、精度も制限されることが挙げられます。 js を使用して Web 上に顔検出を実装するにはどうすればよいですか? Web 上で顔認識を実装するには、JavaScript、HTML、CSS、WebRTC など、関連するプログラミング言語とテクノロジに精通している必要があります。同時に、関連するコンピューター ビジョンと人工知能テクノロジーを習得する必要もあります。 Web 側の設計により、次の点に注意してください。

foreach ループを使用して PHP 配列から重複要素を削除するにはどうすればよいですか? foreach ループを使用して PHP 配列から重複要素を削除するにはどうすればよいですか? Apr 27, 2024 am 11:33 AM

foreach ループを使用して PHP 配列から重複要素を削除する方法は次のとおりです。配列を走査し、要素がすでに存在し、現在の位置が最初に出現しない場合は、要素を削除します。たとえば、データベース クエリの結果に重複レコードがある場合、このメソッドを使用してそれらを削除し、重複レコードのない結果を取得できます。

PHP 配列キー値の反転: さまざまな方法のパフォーマンス比較分析 PHP 配列キー値の反転: さまざまな方法のパフォーマンス比較分析 May 03, 2024 pm 09:03 PM

PHP の配列キー値の反転メソッドのパフォーマンスを比較すると、array_flip() 関数は、大規模な配列 (100 万要素以上) では for ループよりもパフォーマンスが良く、所要時間が短いことがわかります。キー値を手動で反転する for ループ方式は、比較的長い時間がかかります。

PHP 配列ディープ コピーの技術: さまざまな方法を使用して完璧なコピーを実現する PHP 配列ディープ コピーの技術: さまざまな方法を使用して完璧なコピーを実現する May 01, 2024 pm 12:30 PM

PHP で配列をディープ コピーする方法には、json_decode と json_encode を使用した JSON エンコードとデコードが含まれます。 array_map と clone を使用して、キーと値のディープ コピーを作成します。シリアル化と逆シリアル化には、serialize と unserialize を使用します。

PHP 配列の多次元ソートの実践: 単純なシナリオから複雑なシナリオまで PHP 配列の多次元ソートの実践: 単純なシナリオから複雑なシナリオまで Apr 29, 2024 pm 09:12 PM

多次元配列のソートは、単一列のソートとネストされたソートに分類できます。単一列のソートでは、array_multisort() 関数を使用して列ごとにソートできますが、ネストされたソートでは、配列を走査してソートするための再帰関数が必要です。具体的な例としては、製品名による並べ替えや、売上数量や価格による化合物の並べ替えなどがあります。

PHP 配列のディープ コピーのベスト プラクティス: 効率的な方法を発見する PHP 配列のディープ コピーのベスト プラクティス: 効率的な方法を発見する Apr 30, 2024 pm 03:42 PM

PHP で配列のディープ コピーを実行するためのベスト プラクティスは、 json_decode(json_encode($arr)) を使用して配列を JSON 文字列に変換し、それから配列に戻すことです。 unserialize(serialize($arr)) を使用して配列を文字列にシリアル化し、それを新しい配列に逆シリアル化します。 RecursiveIteratorIterator を使用して、多次元配列を再帰的に走査します。

データソートにおけるPHP配列グループ化機能の応用 データソートにおけるPHP配列グループ化機能の応用 May 04, 2024 pm 01:03 PM

PHP の array_group_by 関数は、キーまたはクロージャ関数に基づいて配列内の要素をグループ化し、キーがグループ名、値がグループに属する要素の配列である連想配列を返すことができます。

PHP 配列のマージおよび重複排除アルゴリズム: 並列ソリューション PHP 配列のマージおよび重複排除アルゴリズム: 並列ソリューション Apr 18, 2024 pm 02:30 PM

PHP 配列のマージおよび重複排除アルゴリズムは、元の配列を小さなブロックに分割して並列処理する並列ソリューションを提供し、メイン プロセスは重複排除するブロックの結果をマージします。アルゴリズムのステップ: 元の配列を均等に割り当てられた小さなブロックに分割します。重複排除のために各ブロックを並行して処理します。ブロックの結果をマージし、再度重複排除します。

See all articles