programing

JS 어레이에서 중복된 값 제거

sourcejob 2022. 11. 24. 21:39
반응형

JS 어레이에서 중복된 값 제거

중복이 있을 수도 있고 없을 수도 있는 매우 단순한 JavaScript 배열이 있습니다.

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

중복된 값을 제거하고 새 배열에 고유 값을 넣어야 합니다.

내가 시도했던 모든 코드를 가리킬 수 있지만 작동하지 않기 때문에 소용없다고 생각한다.jQuery 솔루션도 인정합니다.

유사한 질문:

TL;DR

Set 컨스트럭터 및 스프레드 구문을 사용하여 다음 작업을 수행합니다.

uniq = [...new Set(array)];

'스마트'하지만 순진함

uniqueArray = a.filter(function(item, pos) {
    return a.indexOf(item) == pos;
})

기본적으로 배열에 걸쳐 반복하고 각 요소에 대해 배열에서 이 요소의 첫 번째 위치가 현재 위치와 동일한지 확인합니다.이 두 위치는 중복 요소에 대해 서로 다릅니다.

필터 콜백의 세 번째("이 어레이") 파라미터를 사용하면 어레이 변수가 닫히지 않도록 할 수 있습니다.

uniqueArray = a.filter(function(item, pos, self) {
    return self.indexOf(item) == pos;
})

이 알고리즘은 간결하지만 대규모 어레이에 대해서는 특별히 효율적이지 않습니다(2차 시간).

해쉬테이블을 통한 구조

function uniq(a) {
    var seen = {};
    return a.filter(function(item) {
        return seen.hasOwnProperty(item) ? false : (seen[item] = true);
    });
}

보통 이렇게 해요.각 요소를 해시테이블에 배치한 후 그 존재 여부를 즉시 확인하는 것이 목적입니다.이로 인해 선형 시간이 제공되지만 적어도 두 가지 단점이 있습니다.

  • 해시 키는 JavaScript에서는 문자열이나 기호만 사용할 수 있으므로 이 코드는 숫자와 "숫자 문자열"을 구분하지 않습니다.그것은,uniq([1,"1"]) 돌아오다[1]
  • 됩니다.uniq([{foo:1},{foo:2}]) 돌아오다[{foo:1}].

즉, 어레이에 기본 요소만 포함되어 있고 유형(예: 항상 숫자)에 관심이 없는 경우 이 솔루션이 최적입니다.

두 세계의 최고

범용 솔루션은 두 가지 접근 방식을 결합합니다. 즉, 원시 요소에 해시 룩업과 개체에 대한 선형 검색을 사용합니다.

function uniq(a) {
    var prims = {"boolean":{}, "number":{}, "string":{}}, objs = [];

    return a.filter(function(item) {
        var type = typeof item;
        if(type in prims)
            return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true);
        else
            return objs.indexOf(item) >= 0 ? false : objs.push(item);
    });
}

정렬 | uniq

다른 옵션은 먼저 배열을 정렬한 후 이전 요소와 동일한 요소를 제거하는 것입니다.

function uniq(a) {
    return a.sort().filter(function(item, pos, ary) {
        return !pos || item != ary[pos - 1];
    });
}

말하지만,은 사물에 에).sort게다가 부작용으로서 원래의 어레이를 사일런트하게 변경해 버립니다만, 좋지 않습니다. 정렬되어 있는 (이렇게 하면 ).sort위로부터)를 클릭합니다.

독특한 사람...

동일성 이외의 기준에 따라 목록을 통일하는 것이 필요할 수 있습니다.예를 들어, 다른 오브젝트를 필터링하여 일부 속성을 공유하는 등입니다.이는 콜백을 전달함으로써 우아하게 수행할 수 있습니다.이 '키' 콜백은 각 요소에 적용되며 '키'가 동일한 요소는 삭제됩니다.★★key여기서 해시 테이블은 정상적으로 동작합니다.

function uniqBy(a, key) {
    var seen = {};
    return a.filter(function(item) {
        var k = key(item);
        return seen.hasOwnProperty(k) ? false : (seen[k] = true);
    })
}

도움이 되는 " " " 。key()JSON.stringify물리적으로는 다르지만, 「외관」은 같은 오브젝트를 삭제합니다.

a = [[1,2,3], [4,5,6], [1,2,3]]
b = uniqBy(a, JSON.stringify)
console.log(b) // [[1,2,3], [4,5,6]]

경우,key원시적이지 .

function uniqBy(a, key) {
    var index = [];
    return a.filter(function (item) {
        var k = key(item);
        return index.indexOf(k) >= 0 ? false : index.push(k);
    });
}

에서는 ES6를 할 수 .Set:

function uniqBy(a, key) {
    let seen = new Set();
    return a.filter(item => {
        let k = key(item);
        return seen.has(k) ? false : seen.add(k);
    });
}

★★★Map:

function uniqBy(a, key) {
    return [
        ...new Map(
            a.map(x => [key(x), x])
        ).values()
    ]
}

둘 다 비콘솔 키와 함께 작동합니다.

처음이야, 마지막이야?

키를 사용하여 개체를 제거할 때 "동일한" 개체 중 첫 번째 개체 또는 마지막 개체를 유지할 수 있습니다.

하다를 사용하세요.Set에서는 첫 번째를 또, 「 」는 「 」를 참조해 주세요.Map★★★★★★★★★★★★★★★★★★★★★★★:

function uniqByKeepFirst(a, key) {
    let seen = new Set();
    return a.filter(item => {
        let k = key(item);
        return seen.has(k) ? false : seen.add(k);
    });
}


function uniqByKeepLast(a, key) {
    return [
        ...new Map(
            a.map(x => [key(x), x])
        ).values()
    ]
}

//

data = [
    {a:1, u:1},
    {a:2, u:2},
    {a:3, u:3},
    {a:4, u:1},
    {a:5, u:2},
    {a:6, u:3},
];

console.log(uniqByKeepFirst(data, it => it.u))
console.log(uniqByKeepLast(data, it => it.u))

라이브러리

언더스코어Lo-Dash 모두uniq 의 첫 하면 다음과 같습니다.이들 알고리즘은 기본적으로 위의 첫 번째 스니펫과 비슷하며 요약하면 다음과 같습니다.

var result = [];
a.forEach(function(item) {
     if(result.indexOf(item) < 0) {
         result.push(item);
     }
});

2차적인 이지만, 원어민, 원어민, 랩핑 원어민, 랩핑 원어민, 랩핑 원어민, 랩핑 원어민, 랩핑 원어민, 랩핑 원어민, 랩핑 원어민, 랩 원어민, 랩 원어민, 랩 원어민 등, 맛있는 것이 있습니다.indexOf( 「」)iteratee그리고 이미 정렬된 어레이에 대한 최적화도 가능합니다.

jQuery를 사용하고 있는데 1달러가 없으면 아무것도 할 수 없다면 다음과 같습니다.

  $.uniqArray = function(a) {
        return $.grep(a, function(item, pos) {
            return $.inArray(item, a) === pos;
        });
  }

첫 번째 조각의 변형입니다.

성능

함수 호출은 JavaScript에서 비용이 많이 들기 때문에 위의 솔루션은 간결하지만 특별히 효율적이지 않습니다.하려면 , 「」를 .filter루프를 사용하여 다른 함수 호출을 삭제합니다.

function uniq_fast(a) {
    var seen = {};
    var out = [];
    var len = a.length;
    var j = 0;
    for(var i = 0; i < len; i++) {
         var item = a[i];
         if(seen[item] !== 1) {
               seen[item] = 1;
               out[j++] = item;
         }
    }
    return out;
}

이 추악한 코드 덩어리는 위의 3번 부분과 동일하지만, 훨씬 더 빠릅니다(2017년 시점에서는 불과 2배 더 빠릅니다.JS 핵심 직원들이 매우 잘하고 있습니다!)

function uniq(a) {
    var seen = {};
    return a.filter(function(item) {
        return seen.hasOwnProperty(item) ? false : (seen[item] = true);
    });
}

function uniq_fast(a) {
    var seen = {};
    var out = [];
    var len = a.length;
    var j = 0;
    for(var i = 0; i < len; i++) {
         var item = a[i];
         if(seen[item] !== 1) {
               seen[item] = 1;
               out[j++] = item;
         }
    }
    return out;
}

/////

var r = [0,1,2,3,4,5,6,7,8,9],
    a = [],
    LEN = 1000,
    LOOPS = 1000;

while(LEN--)
    a = a.concat(r);

var d = new Date();
for(var i = 0; i < LOOPS; i++)
    uniq(a);
document.write('<br>uniq, ms/loop: ' + (new Date() - d)/LOOPS)

var d = new Date();
for(var i = 0; i < LOOPS; i++)
    uniq_fast(a);
document.write('<br>uniq_fast, ms/loop: ' + (new Date() - d)/LOOPS)

ES6

ES6는 Set 객체를 제공하므로 작업이 훨씬 쉬워집니다.

function uniq(a) {
   return Array.from(new Set(a));
}

또는

let uniq = a => [...new Set(a)];

python과 달리 ES6 세트는 삽입 순서로 반복되므로 이 코드는 원래 배열의 순서를 유지합니다.

그러나 고유한 요소를 포함하는 배열이 필요한 경우 처음부터 세트를 사용하면 어떨까요?

제너레이터

의 '게으른'uniq 같은 베이스로 구축할 수 .

  • 의론에서 다음 값을 취하다
  • 이미 보였으면 건너뜁니다.
  • 그렇지 않은 경우, 산출하여 이미 표시된 값 집합에 추가합니다.

function* uniqIter(a) {
    let seen = new Set();

    for (let x of a) {
        if (!seen.has(x)) {
            seen.add(x);
            yield x;
        }
    }
}

// example:

function* randomsBelow(limit) {
    while (1)
        yield Math.floor(Math.random() * limit);
}

// note that randomsBelow is endless

count = 20;
limit = 30;

for (let r of uniqIter(randomsBelow(limit))) {
    console.log(r);
    if (--count === 0)
        break
}

// exercise for the reader: what happens if we set `limit` less than `count` and why

jQuery를 사용하여 빠르고 지저분함:

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
var uniqueNames = [];
$.each(names, function(i, el){
    if($.inArray(el, uniqueNames) === -1) uniqueNames.push(el);
});

for-loops 또는 jQuery의 모든 나쁜 예에 싫증이 났다.Javascript에는 오늘날 이를 위한 완벽한 도구가 있습니다: 정렬, 매핑, 축소.

기존 순서를 유지하면서 유니크 감소

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

var uniq = names.reduce(function(a,b){
    if (a.indexOf(b) < 0 ) a.push(b);
    return a;
  },[]);

console.log(uniq, names) // [ 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl' ]

// one liner
return names.reduce(function(a,b){if(a.indexOf(b)<0)a.push(b);return a;},[]);

정렬을 통한 빠른 유니크

아마 더 빠른 방법이 있겠지만 이건 꽤 괜찮은 방법이야.

var uniq = names.slice() // slice makes copy of array before sorting it
  .sort(function(a,b){
    return a > b;
  })
  .reduce(function(a,b){
    if (a.slice(-1)[0] !== b) a.push(b); // slice(-1)[0] means last item in array without removing it (like .pop())
    return a;
  },[]); // this empty array becomes the starting value for a

// one liner
return names.slice().sort(function(a,b){return a > b}).reduce(function(a,b){if (a.slice(-1)[0] !== b) a.push(b);return a;},[]);

업데이트 2015: ES6 버전:

ES6에는 Sets and Spread(세트 및 스프레드)가 있어 모든 중복을 매우 쉽고 효과적으로 제거할 수 있습니다.

var uniq = [ ...new Set(names) ]; // [ 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl' ]

발생 기준 정렬:

어떤 분이 고유 이름이 몇 개인지에 따라 결과의 순서를 매기는 것에 대해 질문하셨습니다.

var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']

var uniq = names
  .map((name) => {
    return {count: 1, name: name}
  })
  .reduce((a, b) => {
    a[b.name] = (a[b.name] || 0) + b.count
    return a
  }, {})

var sorted = Object.keys(uniq).sort((a, b) => uniq[a] < uniq[b])

console.log(sorted)

Vanilla JS: 집합과 같은 개체를 사용하여 중복 제거

언제든지 오브젝트에 삽입하고 키를 사용하여 반복할 수 있습니다.

function remove_duplicates(arr) {
    var obj = {};
    var ret_arr = [];
    for (var i = 0; i < arr.length; i++) {
        obj[arr[i]] = true;
    }
    for (var key in obj) {
        ret_arr.push(key);
    }
    return ret_arr;
}

Vanilla JS: 이미 표시된 값을 추적하여 중복 제거(주문 안전)

또는 주문 안전 버전의 경우 개체를 사용하여 이전에 본 모든 값을 저장하고 배열에 추가하기 전에 값을 확인합니다.

function remove_duplicates_safe(arr) {
    var seen = {};
    var ret_arr = [];
    for (var i = 0; i < arr.length; i++) {
        if (!(arr[i] in seen)) {
            ret_arr.push(arr[i]);
            seen[arr[i]] = true;
        }
    }
    return ret_arr;

}

ECMAScript 6: 새로운 Set 데이터 구조 사용(주문 안전)

ECMAScript6을 한다.SetData-Structure: 데이터 구조입니다. Set.values삽입 순서대로 요소를 반환합니다.

function remove_duplicates_es6(arr) {
    let s = new Set(arr);
    let it = s.values();
    return Array.from(it);
}

사용 예:

a = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

b = remove_duplicates(a);
// b:
// ["Adam", "Carl", "Jenny", "Matt", "Mike", "Nancy"]

c = remove_duplicates_safe(a);
// c:
// ["Mike", "Matt", "Nancy", "Adam", "Jenny", "Carl"]

d = remove_duplicates_es6(a);
// d:
// ["Mike", "Matt", "Nancy", "Adam", "Jenny", "Carl"]

어레이를 .filter ★★★★★★★★★★★★★★★★★」.indexOf★★★★

arr = arr.filter(function (value, index, array) { 
  return array.indexOf(value) === index;
});

Underscore.js 사용

어레이를 조작하는 기능이 풍부한 라이브러리입니다.

jQuery의 턱시도와 Backbone.js의 멜빵에 어울리는 넥타이입니다.

_.uniq

_.uniq(array, [isSorted], [iterator])
===를 사용하여 개체 동일성을 테스트하여 어레이의 중복 없는 버전을 생성합니다.배열이 정렬된 것을 미리 알고 있는 경우 isSorted에 대해 true를 전달하면 훨씬 빠른 알고리즘이 실행됩니다.변환을 기반으로 고유한 항목을 계산하려면 반복기 함수를 전달하십시오.

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

alert(_.uniq(names, false));

주의: Lo-Dash(언더스코어 경쟁사)는 동등한 .uniq 구현도 제공합니다.

한 줄:

let names = ['Mike','Matt','Nancy','Adam','Jenny','Nancy','Carl', 'Nancy'];
let dup = [...new Set(names)];
console.log(dup);

JavaScript의 두 - JavaScript에서 할 수.filter★★★★

var a = [2,3,4,5,5,4];
a.filter(function(value, index){ return a.indexOf(value) == index });

또는 짧게 말하면

a.filter((v,i) => a.indexOf(v) == i)

Array.filter()

var actualArr = ['Apple', 'Apple', 'Banana', 'Mango', 'Strawberry', 'Banana'];

console.log('Actual Array: ' + actualArr);

var filteredArr = actualArr.filter(function(item, index) {
  if (actualArr.indexOf(item) == index)
    return item;
});

console.log('Filtered Array: ' + filteredArr);

이것은 ES6에서 더 짧아질 수 있습니다.

actualArr.filter((item,index,self) => self.indexOf(item)==index);

여기 좋은 설명이 있습니다.Array.filter()

네이티브 javascript 함수를 사용하여 어레이에서 중복을 제거하는 가장 간결한 방법은 다음과 같은 시퀀스를 사용하는 것입니다.

vals.sort().reduce(function(a, b){ if (b != a[0]) a.unshift(b); return a }, [])

없다slice 않다indexOf다른 예에서 보듯이 축소 기능 내에서! 필터 기능과 함께 사용하는 것은 의미가 있습니다.

vals.filter(function(v, i, a){ return i == a.indexOf(v) })

또한 ES6(2015)에서는 이미 몇 개의 브라우저에서 사용할 수 있는 다른 방법이 있습니다.

Array.from(new Set(vals))

또는 확산 연산자를 사용할 수도 있습니다.

[...new Set(vals)]

건배!

.O(n²), 이 은 「」, 「」으로 할 수 O(n)개체를 해시로 사용하여 다음을 수행합니다.

function getDistinctArray(arr) {
    var dups = {};
    return arr.filter(function(el) {
        var hash = el.valueOf();
        var isDup = dups[hash];
        dups[hash] = true;
        return !isDup;
    });
}

문자열, 숫자 및 날짜에 사용할 수 있습니다.오브젝트가 되어 있는 의 솔루션은 되었을 때 은 ""입니다."[object Object]"(또는 유사한 것)로 검색 값으로 적합하지 않습니다.O(n)오브젝트 자체에 플래그를 설정하여 오브젝트를 구현합니다.

function getDistinctObjArray(arr) {
    var distinctArr = arr.filter(function(el) {
        var isDup = el.inArray;
        el.inArray = true;
        return !isDup;
    });
    distinctArr.forEach(function(el) {
        delete el.inArray;
    });
    return distinctArr;
}

2019년 편집:최신 버전의 JavaScript는 이를 훨씬 쉽게 해결할 수 있도록 합니다.사용.Set는 배열에 객체, 문자열, 숫자 또는 기타 유형이 포함되어 있는지 여부에 관계없이 작동합니다.

function getDistinctArray(arr) {
    return [...new Set(arr)];
}

구현이 매우 간단하기 때문에 함수를 정의할 필요가 없습니다.

내가 지금까지 마주친 것 중 가장 간단한 것.es6에서.

 var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl", "Mike", "Nancy"]

 var noDupe = Array.from(new Set(names))

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

ECMAScript 6(ECMAScript 2015라고도 함)에서는 중복을 필터링하기 위해 를 사용할 수 있습니다.그런 다음 확산 연산자를 사용하여 배열로 다시 변환할 수 있습니다.

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"],
    unique = [...new Set(names)];

솔루션 1

Array.prototype.unique = function() {
    var a = [];
    for (i = 0; i < this.length; i++) {
        var current = this[i];
        if (a.indexOf(current) < 0) a.push(current);
    }
    return a;
}

솔루션 2(세트 사용)

Array.prototype.unique = function() {
    return Array.from(new Set(this));
}

시험

var x=[1,2,3,3,2,1];
x.unique() //[1,2,3]

성능

크롬으로 구현(Set 유무)을 테스트해 본 결과, Set이 훨씬 빠릅니다!

Array.prototype.unique1 = function() {
    var a = [];
    for (i = 0; i < this.length; i++) {
        var current = this[i];
        if (a.indexOf(current) < 0) a.push(current);
    }
    return a;
}


Array.prototype.unique2 = function() {
    return Array.from(new Set(this));
}

var x=[];
for(var i=0;i<10000;i++){
	x.push("x"+i);x.push("x"+(i+1));
}

console.time("unique1");
console.log(x.unique1());
console.timeEnd("unique1");



console.time("unique2");
console.log(x.unique2());
console.timeEnd("unique2");

이거 하나 하자.

var uniqueArray = duplicateArray.filter(function(elem, pos) {
    return duplicateArray.indexOf(elem) == pos;
}); 

이제 uniqueArray에 중복된 항목이 없습니다.

다음은 나열된 jQuery 메서드보다 80% 이상 빠릅니다(아래 테스트 참조).몇 년 전 비슷한 질문의 답변이다.처음 제안한 사람을 만나면 크레딧을 게시하겠습니다.순수 JS

var temp = {};
for (var i = 0; i < array.length; i++)
  temp[array[i]] = true;
var r = [];
for (var k in temp)
  r.push(k);
return r;

테스트 케이스 비교: http://jsperf.com/remove-duplicate-array-tests

나는 다른 질문에서 속임수 제거에 대한 자세한 비교를 했지만, 이것이 내가 단지 여기서 그것을 공유하고 싶었던 진짜 장소라는 것을 알아차렸다.

이게 제일 좋은 방법인 것 같아

var myArray = [100, 200, 100, 200, 100, 100, 200, 200, 200, 200],
    reduced = Object.keys(myArray.reduce((p,c) => (p[c] = true,p),{}));
console.log(reduced);

네, 이것은 O(n)이고 다른 것은 O(n^2)이지만, 저는 이 축소/룩업 테이블과 필터/index Of 콤보의 벤치마크 비교가 궁금했습니다(저는 Jeetendras very nice implementation https://stackoverflow.com/a/37441144/4543207)을 선택했습니다).0~9999 범위의 임의의 양의 정수로 채워진 10K 아이템 배열을 준비하면 중복이 제거됩니다.테스트를 10번 반복했는데 평균 결과에서 성능이 비교가 안 됩니다.

  • 파이어폭스 v47에서는 필터 및 인덱스 Of: 2836ms에 비해 감소 및 감소: 14.85ms
  • 크롬 v51에서는 필터 및 인덱스 Of: 1066 ms에 비해 감소 & LUT: 23.90 ms

아직까진 괜찮아.하지만 이번에는 ES6 스타일로 제대로 합시다.너무 멋있어 보여..!하지만 지금으로서는 강력한 LUT 솔루션에 대해 어떻게 기능할지는 미스터리입니다.먼저 코드를 보고 벤치마크를 해보겠습니다.

var myArray = [100, 200, 100, 200, 100, 100, 200, 200, 200, 200],
    reduced = [...myArray.reduce((p,c) => p.set(c,true),new Map()).keys()];
console.log(reduced);

와 짧다..!하지만 공연은 어때?아름답네요...필터/indexOf의 무거운 무게가 어깨 위로 올라갔기 때문에 나는 범위 0의 양의 정수 배열 100만 개의 랜덤 항목을 테스트할 수 있다.99999: 10회 연속 테스트에서 평균을 얻습니다.이번에는 진짜 승부라고 말할 수 있어요.결과를 직접 확인하세요:)

var ranar = [],
     red1 = a => Object.keys(a.reduce((p,c) => (p[c] = true,p),{})),
     red2 = a => reduced = [...a.reduce((p,c) => p.set(c,true),new Map()).keys()],
     avg1 = [],
     avg2 = [],
       ts = 0,
       te = 0,
     res1 = [],
     res2 = [],
     count= 10;
for (var i = 0; i<count; i++){
  ranar = (new Array(1000000).fill(true)).map(e => Math.floor(Math.random()*100000));
  ts = performance.now();
  res1 = red1(ranar);
  te = performance.now();
  avg1.push(te-ts);
  ts = performance.now();
  res2 = red2(ranar);
  te = performance.now();
  avg2.push(te-ts);
}

avg1 = avg1.reduce((p,c) => p+c)/count;
avg2 = avg2.reduce((p,c) => p+c)/count;

console.log("reduce & lut took: " + avg1 + "msec");
console.log("map & spread took: " + avg2 + "msec");

어떤 것을 사용하시겠습니까?글쎄, 그렇게 빨리...!속지 마세요.지도가 변위 중입니다.자, 보세요...위의 경우 모두 크기 n의 배열에 범위 < n의 번호를 채웁니다.즉, 크기가 100인 배열과 난수 0.9로 채웁니다.따라서 중복되는 것이 확실하고 "거의" 각 번호가 중복되는 것이 확실합니다.100의 배열을 0~9999의 난수로 채우는 것은 어떨까요?이제 집에서 지도를 재생해 보겠습니다.이번에는 10만 개 항목 배열이지만 난수 범위는 0~100M입니다.100회 연속 테스트를 실시하여 평균 결과를 산출합니다.좋아, 내기를 보자구.<-오타 없음

var ranar = [],
     red1 = a => Object.keys(a.reduce((p,c) => (p[c] = true,p),{})),
     red2 = a => reduced = [...a.reduce((p,c) => p.set(c,true),new Map()).keys()],
     avg1 = [],
     avg2 = [],
       ts = 0,
       te = 0,
     res1 = [],
     res2 = [],
     count= 100;
for (var i = 0; i<count; i++){
  ranar = (new Array(100000).fill(true)).map(e => Math.floor(Math.random()*100000000));
  ts = performance.now();
  res1 = red1(ranar);
  te = performance.now();
  avg1.push(te-ts);
  ts = performance.now();
  res2 = red2(ranar);
  te = performance.now();
  avg2.push(te-ts);
}

avg1 = avg1.reduce((p,c) => p+c)/count;
avg2 = avg2.reduce((p,c) => p+c)/count;

console.log("reduce & lut took: " + avg1 + "msec");
console.log("map & spread took: " + avg2 + "msec");

이번에는 Map()의 화려한 컴백입니다!지금이야말로 당신이 그 속임수를 제거하고 싶을 때 더 나은 결정을 내릴 수 있을 것이다.

좋아, 우리 모두 지금 행복해.하지만 주인공은 항상 박수갈채를 받으며 마지막에 온다.세트 오브젝트가 뭘 할지 궁금하신 분들도 있을 거예요.ES6에 오픈되어 있고 Map이 이전 게임의 승자라는 것을 알았으므로 결승전의 Map과 Set을 비교해 보겠습니다.이번에는 전형적인 레알 마드리드 대 바르셀로나 경기...아니면 그러한가?엘 클래식에서 누가 우승할지 지켜봅시다:)

var ranar = [],
     red1 = a => reduced = [...a.reduce((p,c) => p.set(c,true),new Map()).keys()],
     red2 = a => Array.from(new Set(a)),
     avg1 = [],
     avg2 = [],
       ts = 0,
       te = 0,
     res1 = [],
     res2 = [],
     count= 100;
for (var i = 0; i<count; i++){
  ranar = (new Array(100000).fill(true)).map(e => Math.floor(Math.random()*10000000));
  ts = performance.now();
  res1 = red1(ranar);
  te = performance.now();
  avg1.push(te-ts);
  ts = performance.now();
  res2 = red2(ranar);
  te = performance.now();
  avg2.push(te-ts);
}

avg1 = avg1.reduce((p,c) => p+c)/count;
avg2 = avg2.reduce((p,c) => p+c)/count;

console.log("map & spread took: " + avg1 + "msec");
console.log("set & A.from took: " + avg2 + "msec");

와.. 야..!음, 예상외로 그것은 전혀 고전이 아닌 것으로 판명되었다.바르셀로나 FC와 CA Osasuna의 대결에 가깝습니다. : )

여기 그 질문에 대한 간단한 답이 있다.

var names = ["Alex","Tony","James","Suzane", "Marie", "Laurence", "Alex", "Suzane", "Marie", "Marie", "James", "Tony", "Alex"];
var uniqueNames = [];

    for(var i in names){
        if(uniqueNames.indexOf(names[i]) === -1){
            uniqueNames.push(names[i]);
        }
    }

A simple but effective technique, is to use the 간단하지만 효과적인 기술은 다음과 같습니다.filter method in combination with the filter 필터와 조합한 메서드function(value, index){ return this.indexOf(value) == index }....

코드 예:

var data = [2,3,4,5,5,4];
var filter = function(value, index){ return this.indexOf(value) == index };
var filteredData = data.filter(filter, data );

document.body.innerHTML = '<pre>' + JSON.stringify(filteredData, null, '\t') +  '</pre>';

바이올린을 참조하십시오.

옵션은 다음과 같습니다.

let a = [11,22,11,22];
let b = []


b = [ ...new Set(a) ];     
// b = [11, 22]

b = Array.from( new Set(a))   
// b = [11, 22]

b = a.filter((val,i)=>{
  return a.indexOf(val)==i
})                        
// b = [11, 22]

여기에서는 Photoshop Script 코드도 쉽게 이해하고 작업할 수 있습니다.그것을 조사하시오!

var peoplenames = new Array("Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl");

peoplenames = unique(peoplenames);
alert(peoplenames);

function unique(array){
    var len = array.length;
    for(var i = 0; i < len; i++) for(var j = i + 1; j < len; j++) 
        if(array[j] == array[i]){
            array.splice(j,1);
            j--;
            len--;
        }
    return array;
}

//*result* peoplenames == ["Mike","Matt","Nancy","Adam","Jenny","Carl"]

여기 특별한 라이브러리가 없는 간단한 방법이 특별한 기능이다.

name_list = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
get_uniq = name_list.filter(function(val,ind) { return name_list.indexOf(val) == ind; })

console.log("Original name list:"+name_list.length, name_list)
console.log("\n Unique name list:"+get_uniq.length, get_uniq)

여기에 이미지 설명 입력

현재의 답변보다 심플하고 간결한 솔루션(미래를 내다보는 ES6 솔루션 제외)일 뿐만 아니라, 이것을 테스트해 본 결과, 매우 고속으로 되어 있었습니다.

var uniqueArray = dupeArray.filter(function(item, i, self){
  return self.lastIndexOf(item) == i;
});

한 가지 주의사항:Array. lastIndex Of()는 IE9에 추가되어 있기 때문에, 그 이하가 필요한 경우는, 다른 곳을 참조할 필요가 있습니다.

일반적인 기능적 접근법

다음은 ES2015의 일반적이고 엄격하게 기능하는 접근법입니다.

// small, reusable auxiliary functions

const apply = f => a => f(a);

const flip = f => b => a => f(a) (b);

const uncurry = f => (a, b) => f(a) (b);

const push = x => xs => (xs.push(x), xs);

const foldl = f => acc => xs => xs.reduce(uncurry(f), acc);

const some = f => xs => xs.some(apply(f));


// the actual de-duplicate function

const uniqueBy = f => foldl(
   acc => x => some(f(x)) (acc)
    ? acc
    : push(x) (acc)
 ) ([]);


// comparators

const eq = y => x => x === y;

// string equality case insensitive :D
const seqCI = y => x => x.toLowerCase() === y.toLowerCase();


// mock data

const xs = [1,2,3,1,2,3,4];

const ys = ["a", "b", "c", "A", "B", "C", "D"];


console.log( uniqueBy(eq) (xs) );

console.log( uniqueBy(seqCI) (ys) );

We can easily derive 우리는 쉽게 도출할 수 있다.unique부에서unqiueBy or use the faster implementation utilizing 또, 보다 고속의 실장도 이용할 수 있습니다.SetS: 네.

const unqiue = uniqueBy(eq);

// const unique = xs => Array.from(new Set(xs));

이 접근방식의 이점:

  • 다른 대조군 함수를 사용한 범용 솔루션
  • 선언적이고 간결한 실시
  • 기타 소규모 범용 기능의 재사용

퍼포먼스에 관한 고려사항

uniqueBy루프가 루프를 가진 것은 아니지만, 세대 때문에, 세대 때문에 더 표현하기가 훨씬 더 표현된다.루프를 수반하는 필수 구현만큼 빠르지는 않지만 범용성이 있기 때문에 훨씬 표현력이 뛰어납니다.

「 」를 uniqueBy앱의 구체적인 성능 저하 원인으로서 최적화된 코드로 대체하십시오.이고 선언적인.그 후 성능 문제가 발생한 경우 문제의 원인인 위치에서 코드를 최적화해 보십시오.

메모리 소비량 및 가비지 수집

uniqueBy돌연변이)를 이용하다push(x) (acc) )이 본체 에 숨겨져 있습니다이 몸 안에 숨겨져 있습니다.반복할 때마다 어큐뮬레이터를 폐기하는 대신 어큐뮬레이터를 재사용합니다.이것에 의해, 메모리 소비량과 GC의 압력이 저감 됩니다.이 부작용은 기능 안에 싸여 있기 때문에 외부의 모든 것이 순수하게 유지됩니다.

for (i=0; i<originalArray.length; i++) {  
    if (!newArray.includes(originalArray[i])) {
        newArray.push(originalArray[i]); 
    }
}

다음 스크립트는 고유한 값만 포함하는 새 어레이를 반환합니다.그것은 문자열과 숫자로 작동한다.추가 라이브러리는 vanilla JS에만 필요하지 않습니다.

브라우저 지원:

Feature Chrome  Firefox (Gecko)     Internet Explorer   Opera   Safari
Basic support   (Yes)   1.5 (1.8)   9                   (Yes)   (Yes)

https://jsfiddle.net/fzmcgcxv/3/

var duplicates = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl","Mike","Mike","Nancy","Carl"]; 
var unique = duplicates.filter(function(elem, pos) {
    return duplicates.indexOf(elem) == pos;
  }); 
alert(unique);

혹시 당신이 이 장치를 사용하고 있다면

D3.js

할 수 있다

d3.set(["foo", "bar", "foo", "baz"]).values() ==> ["foo", "bar", "baz"]

https://github.com/mbostock/d3/wiki/Arrays#set_values

커스텀 컴퍼레이터를 사용하기 위한 thg435의 우수한 답변의 약간의 수정:

function contains(array, obj) {
    for (var i = 0; i < array.length; i++) {
        if (isEqual(array[i], obj)) return true;
    }
    return false;
}
//comparator
function isEqual(obj1, obj2) {
    if (obj1.name == obj2.name) return true;
    return false;
}
function removeDuplicates(ary) {
    var arr = [];
    return ary.filter(function(x) {
        return !contains(arr, x) && arr.push(x);
    });
}
$(document).ready(function() {

    var arr1=["dog","dog","fish","cat","cat","fish","apple","orange"]

    var arr2=["cat","fish","mango","apple"]

    var uniquevalue=[];
    var seconduniquevalue=[];
    var finalarray=[];

    $.each(arr1,function(key,value){

       if($.inArray (value,uniquevalue) === -1)
       {
           uniquevalue.push(value)

       }

    });

     $.each(arr2,function(key,value){

       if($.inArray (value,seconduniquevalue) === -1)
       {
           seconduniquevalue.push(value)

       }

    });

    $.each(uniquevalue,function(ikey,ivalue){

        $.each(seconduniquevalue,function(ukey,uvalue){

            if( ivalue == uvalue)

            {
                finalarray.push(ivalue);
            }   

        });

    });
    alert(finalarray);
});

https://jsfiddle.net/2w0k5tz8/

function remove_duplicates(array_){
    var ret_array = new Array();
    for (var a = array_.length - 1; a >= 0; a--) {
        for (var b = array_.length - 1; b >= 0; b--) {
            if(array_[a] == array_[b] && a != b){
                delete array_[b];
            }
        };
        if(array_[a] != undefined)
            ret_array.push(array_[a]);
    };
    return ret_array;
}

console.log(remove_duplicates(Array(1,1,1,2,2,2,3,3,3)));

어레이 인덱스가 업데이트되지 않으므로 루프스루, 중복 제거 및 복제 어레이 자리 표시자를 만듭니다.

퍼포먼스 향상을 위해 루프백(루프가 어레이 길이를 계속 확인할 필요가 없음)

언급URL : https://stackoverflow.com/questions/9229645/remove-duplicate-values-from-js-array

반응형