ディレクトリ
#1. 二層循環
const unique = (arr)=>{ for(let i = 0; i { var arr = [1, '1', '1', 1, 2, true, false, true, 3, 2, 2, 1]; var newArr = []; for(let i = 0; i <strong>#コアポイント:</strong><p><strong>時間計算量: </strong>O(n^2)</p>
上記実装方法は確かに最良の選択ではありませんが、互換性は良好です~2.1indexOf により 1 レベルのループ判定が簡素化されます
コアポイント:元の配列を返す必要がある場合は、indexOf
メソッドで重複した項目を見つけることができます (最初に出現した位置と等しくない)
indexOf
を削除する場合: 指定された要素が可能な場所の
indexOf(ele, fromIndex)
fromIndex: 検索する要素の開始位置、デフォルトは 0、負の数値が許可されます、-2 は最後から 2 番目から開始することを意味します要素 const unique = (arr) => { var res = []; for (let i = 0; i 2.2 に含まれるループ判定の 1 層を簡素化<p><strong></strong>コアポイント:</p><h5></h5><p>元の配列を返すか新しい配列を返すかに関係なく、自分で組み合わせることができます~<strong></strong></p>includes
を返します。 ##includes(ele, fromIndex)
ele: 検索する要素 fromIndex
インデックスの絶対値だけ前にジャンプします。 。
const unique = (arr) => { var res = []; for (let i = 0; i
ここでは、要素を検索するために include を使用することをお勧めします。
戻り値は、簡潔な if の条件文として直接使用できます。if(res.indexOf(arr[i]) !== -1 ){ todo }// orif(res.includes(arr[i])){ todo }
識別
NaN配列に
NaN があり、配列が存在するかどうかを判断するだけでよい場合 NaN
の場合は、 indexOf
includes メソッドを使用する必要があります。
var arr = [NaN, NaN];arr.indexOf(NaN); // -1arr.includes(NaN); // true
識別 未定義
配列に 未定義値がある場合、includes
は 空の値は未定義です
indexOf は考えません。
var arr = new Array(3);console.log(arr.indexOf(undefined)); //-1console.log(arr.includes(undefined)) //true
3. 並べ替えと重複排除
核心点:配列が並べ替えられた後も、要素は隣接するため、現在の要素が隣接する要素と異なる場合は、新しい配列に格納されます。
indexOf と比較すると、必要なループは 1 つだけです。concat は、 arrays を実行し、新しい配列を返します。
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">var arr = [1, 1, '1'];function unique(arr) {
var res = [];
var sortedArr = arr.concat().sort();
var last;
for (var i = 0; i </pre><div class="contentsignin">ログイン後にコピー</div></div>
#4、フィルター#コアポイント:
filter: メソッドは、提供された 関数によって実装されたテスト のすべての要素を含む新しい配列を作成します (テスト関数が対象とする要素を返します)確立された)
filter(callback, thisArg):
thisArg: コールバックの実行時に this に使用される値。
フィルターを使用すると、コード レベルで外側のループを簡素化できます:
var arr = [1, 2, 1, 1, '1'];const unique = function (arr) { var res = arr.filter(function(item, index, arr){ return arr.indexOf(item) === index; }) return res;}console.log(unique(arr)); // [ 1, 2, '1' ]
var arr = [1, 2, 1, 1, '1'];const unique = function (arr) { return arr.concat().sort().filter(function(item, index, arr){ return !index || item !== arr[index - 1] })}console.log(unique(arr));
上記のメソッドは、大きく分けて
非ソート配列、2 つの走査判定 (トラバーサル、クエリ)
ソートされた配列、隣接する要素の比較
オブジェクト オブジェクト メソッドのキーと値を使用して、要素の数をカウントする別の方法を提案します。配列に現れる場合、2 つの予備判定ロジックがあります。Takeobj
的key
而不管他们的value
var arr = [1, 2, 1, 1, '1', 3, 3];const unique = function(arr) { var obj = {}; var res = []; arr.forEach(item => { if (!obj[item]) { obj[item] = true; res.push(item); } }); return res;}console.log(unique(arr)); // [1, 2, 3]
var arr = [1, 2, 1, 1, '1'];const unique = function(arr) { var obj = {}; return arr.filter(function(item, index, arr){ return obj.hasOwnProperty(item) ? false : (obj[item] = true) })}console.log(unique(arr)); // [1, 2]
对象的属性是字符串类型的,即本身数字1
和字符串‘1’
是不同的,但保存到对象中时会发生隐式类型转换,导致去重存在一定的隐患。
考虑到string和number的区别(typeof 1 === ‘number’, typeof ‘1’ === ‘string’),
所以我们可以使用 typeof item + item
拼成字符串作为 key 值来避免这个问题:
var arr = [1, 2, 1, 1, '1', 3, 3, '2'];const unique = function(arr) { var obj = {}; var res = []; arr.forEach(item => { if (!obj[typeof item + item]) { obj[typeof item + item] = true; res.push(item); } }); return res;}console.log(unique(arr)); // [ 1, 2, '1', 3, '2' ]
六、ES6
随着 ES6 的到来,去重的方法又有了进展,比如我们可以使用 Set 和 Map 数据结构。
Set:它允许你存储任何类型的唯一值,无论是原始值或者是对象引用
代码:
var arr = [1, 2, 1, '1', '2'];const unique = function(arr) { return Array.from(new Set(arr));}console.log(unique(arr)); // [ 1, 2, '1', '2' ]
简化1:
function unique(array) { return [...new Set(array)];}
简化2:
var unique = (a) => [...new Set(a)]
Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。
function unique (arr) { const newMap = new Map() return arr.filter((a) => !newMap.has(a) && newMap.set(a, 1));}
写到这里比较常规的数组去重方法就总结的差不多了,如果需要更强大的去重方法,我们需要对他们进行组合,而且因为场景的不同,我们所实现的方法并不一定能涵盖到
相关免费学习推荐:javascript(视频)
以上がJavaScript トピック 2: 配列の重複排除の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。