>  기사  >  웹 프론트엔드  >  JavaScript 배열 중복 제거 방법

JavaScript 배열 중복 제거 방법

小云云
小云云원래의
2017-11-27 09:24:501309검색

우리 모두는 다양한 프로그래밍 언어에 배열 중복 제거 기능이 있다는 것을 알고 있습니다. 이 기사에서는 모든 사람에게 도움이 되기를 바라면서 JavaScript 배열 중복 제거에 대해 이야기하겠습니다.

Double-level loop

아마도 우리가 가장 먼저 생각하는 것은 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"]

이 방법에서는 루프를 사용합니다. 중첩, 가장 바깥쪽 루프는 배열이고 내부 루프는 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));

정렬 후 중복 제거

정렬 방법을 사용하여 중복 제거된 배열을 먼저 정렬하면 동일한 값이 함께 정렬되고 그런 다음 현재 요소가 이전 요소와 동일한지 판단하면 됩니다. 동일하지 않으면 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));

만약 정렬된 배열의 중복을 제거합니다. 이 방법은 indexOf를 사용하는 것보다 효율성이 확실히 높습니다.

unique API

이 두 가지 방법을 알고 나면 고유라는 도구 함수를 작성해 볼 수 있습니다. 매개변수 isSorted를 기반으로 들어오는 배열이 중복되는지 여부를 판단합니다. 그것이 true이면 해당 인접 요소가 있는지 여부를 판단합니다. 동일하고 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]

Optimization

unqique는 이미 중복 제거 기능을 시도할 수 있지만 이 API를 더욱 강력하게 만들기 위해 다음 요구 사항을 고려해 보겠습니다.

새 요구 사항: 문자 위쪽 및 아래쪽 대소문자는 'a' 및 'A'와 같이 일관성이 있는 것으로 간주됩니다. 하나만 유지하세요!

모든 문자를 소문자로 변환하는 등 배열의 모든 데이터를 먼저 처리한 다음 고유 함수에 전달할 수 있지만 배열 처리 루프를 생략하고 바로 중복 제거로 이동할 수 있는 방법이 있습니까? 루프를 중국에서 하는 것은 어떻습니까? 이 요구 사항을 완료해 보겠습니다.

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]

이 구현과 마지막 버전에서 함수는 세 가지 매개 변수를 전달합니다.

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줄의 코드로 바뀌었는데, 이는 실제로 자바스크립트 언어가 지속적으로 발전하고 있음을 보여주며 앞으로의 개발은 점점 더 효율적이 될 것이라고 믿습니다.

특수 유형 비교

중복 제거 방법은 여기서 끝입니다. 그러나 중복 제거할 요소의 유형은 예시의 단순한 1과 '1' 외에도 실제로는 null, undefine, 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, 정의되지 않음, 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.