etc./StackOverFlow

JavaScript 배열의 모든 고유 값 가져오기(중복 제거)

청렴결백한 만능 재주꾼 2021. 12. 8. 01:19
반응형

질문자 :Mottie


고유한지 확인해야 하는 일련의 숫자가 있습니다. 인터넷에서 아래 코드 조각을 찾았고 배열에 0이 있을 때까지 잘 작동합니다. Stack Overflow에서 거의 비슷하게 보이는 다른 스크립트를 찾았지만 실패하지 않습니다.

그래서 제가 배우는 데 도움을 주기 위해 누군가 프로토타입 스크립트가 어디에서 잘못되고 있는지 알아내도록 도와줄 수 있습니까?

 Array.prototype.getUnique = function() { var o = {}, a = [], i, e; for (i = 0; e = this[i]; i++) {o[e] = 1}; for (e in o) {a.push (e)}; return a; }

중복 질문에 대한 추가 답변:

비슷한 질문:



JavaScript 1.6 / ECMAScript 5 filter 메서드를 사용하여 고유한 값이 있는 배열을 얻을 수 있습니다.

 function onlyUnique(value, index, self) { return self.indexOf(value) === index; } // usage example: var a = ['a', 1, 'a', 2, '1']; var unique = a.filter(onlyUnique); console.log(unique); // ['a', 1, 2, '1']

기본 메서드 filter 는 배열을 반복하고 지정된 콜백 함수 onlyUnique 를 전달하는 항목만 남겨둡니다.

onlyUnique 는 주어진 값이 처음 나타나는지 확인합니다. 그렇지 않은 경우 중복되어야 하며 복사되지 않습니다.

이 솔루션은 jQuery 또는 prototype.js와 같은 추가 라이브러리 없이 작동합니다.

값 유형이 혼합된 배열에서도 작동합니다.

오래된 브라우저 (<IE9), 즉, 네이티브 메소드를 지원하지 않는 filterindexOf 당신을위한 MDN 문서의 작업 방법 찾을 수 있습니다 필터같이 IndexOf를 .

값의 마지막 항목을 유지하려면 indexOflastIndexOf 간단히 바꾸십시오.

ES6을 사용하면 다음과 같이 줄일 수 있습니다.

 // usage example: var myArray = ['a', 1, 'a', 2, '1']; var unique = myArray.filter((v, i, a) => a.indexOf(v) === i); console.log(unique); // unique is ['a', 1, 2, '1']

의견에 힌트를 준 Camilo Martin 에게 감사드립니다.

ES6에는 고유한 값을 저장하는 기본 개체 Set 고유한 값을 가진 배열을 얻으려면 이제 다음을 수행할 수 있습니다.

 var myArray = ['a', 1, 'a', 2, '1']; let unique = [...new Set(myArray)]; console.log(unique); // unique is ['a', 1, 2, '1']

Set 의 생성자는 Array와 같은 반복 가능한 객체를 취하고, 확산 연산자는 ... 집합을 다시 Array로 변환합니다. 의견에 힌트를 준 Lukas Liese 에게 감사드립니다.

다중 배열

 var a = [[2,4],[2,3],[1,3],[1,3],[1,8]] var unique = (value, index, self) =>{ var findIndex = (element) => element[0] == value[0]; return self.findIndex(findIndex) === index; } console.log(a.filter(unique))

TLindig

ES6/ES2015에 대한 업데이트된 답변 : SetSpread 연산자를 사용하면 ( le-m 덕분에) 한 줄 솔루션은 다음과 같습니다.

 let uniqueItems = [...new Set(items)]

어떤 반환

 [4, 5, 6, 3, 2, 23, 1]

A.T.

4가지 가능한 솔루션에 대한 모든 답변을 나눕니다.

  1. 객체 { } 를 사용하여 중복 방지
  2. 도우미 배열 사용 [ ]
  3. filter + indexOf
  4. 보너스! ES6 Sets 방법.

답변에서 찾은 샘플 코드는 다음과 같습니다.

객체 { } 를 사용하여 중복 방지

 function uniqueArray1( ar ) { var j = {}; ar.forEach( function(v) { j[v+ '::' + typeof v] = v; }); return Object.keys(j).map(function(v){ return j[v]; }); }

도우미 배열 사용 [ ]

 function uniqueArray2(arr) { var a = []; for (var i=0, l=arr.length; i<l; i++) if (a.indexOf(arr[i]) === -1 && arr[i] !== '') a.push(arr[i]); return a; }

filter + indexOf

 function uniqueArray3(a) { function onlyUnique(value, index, self) { return self.indexOf(value) === index; } // usage var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1'] return unique; }

ES6 사용 [...new Set(a)]

 function uniqueArray4(a) { return [...new Set(a)]; }

그리고 어느 쪽이 더 빠른지 궁금했습니다. 기능을 테스트하기 위해 샘플 Google Sheet 를 만들었습니다. 참고: ECMA 6은 Google 스프레드시트에서 사용할 수 없으므로 테스트할 수 없습니다.

테스트 결과는 다음과 같습니다. 여기에 이미지 설명 입력

해시를 사용하기 때문에 { } 를 사용하는 코드가 승리할 것이라고 예상했습니다. 따라서 Chrome 및 IE에서 이 알고리즘에 대한 테스트가 최상의 결과를 보여줘서 기쁩니다. 코드에 대해 @rab에게 감사드립니다.

2020년 업데이트

Google 스크립트는 ES6 엔진을 지원합니다. Sets 하여 마지막 코드를 테스트했으며 개체 메서드보다 빠르게 나타났습니다.


Max Makhrov

underscore.js를 사용할 수도 있습니다.

 console.log(_.uniq([1, 2, 1, 3, 1, 4]));
 <script src="http://underscorejs.org/underscore-min.js"></script>

다음을 반환합니다.

 [1, 2, 3, 4]

kornfridge

One Liner, 순수 JavaScript

ES6 구문 사용

list = list.filter((x, i, a) => a.indexOf(x) == i)

 x --> item in array i --> index of item a --> array reference, (in this case "list")

여기에 이미지 설명 입력

ES5 구문 사용

 list = list.filter(function (x, i, a) { return a.indexOf(x) == i; });

브라우저 호환성 : IE9+


Vamsi

그 이후로 jQuery를 사용하는 멋진 방법을 찾았습니다.

 arr = $.grep(arr, function(v, k){ return $.inArray(v ,arr) === k; });

참고: 이 코드는 Paul Irish의 오리 펀치 포스트 에서 가져왔습니다.


Mottie

여기에 있는 많은 답변이 초보자에게 유용하지 않을 수 있습니다. 배열 중복 제거가 어렵다면 프로토타입 체인이나 jQuery에 대해 정말로 알 수 있을까요?

최신 브라우저에서 깨끗하고 간단한 솔루션은 고유한 값 목록으로 설계된 Set 에 데이터를 저장하는 것입니다.

 const cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford']; const uniqueCars = Array.from(new Set(cars)); console.log(uniqueCars);

Array.from 은 Set을 다시 Array로 변환하는 데 유용하므로 배열에 있는 모든 멋진 메서드(기능)에 쉽게 액세스할 수 있습니다. 같은 일을 하는 다른 방법 도 있습니다. 그러나 Sets에는 forEach 와 같은 유용한 기능이 많이 Array.from 이 전혀 필요하지 않을 수도 있습니다.

이전 Internet Explorer를 지원해야 하므로 Set을 사용할 수 없는 경우 간단한 기술은 항목이 이미 새 배열에 있는지 확인하면서 새 배열에 항목을 복사하는 것입니다.

 // Create a list of cars, with duplicates. var cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford']; // Create a list of unique cars, to put a car in if we haven't already. var uniqueCars = []; // Go through each car, one at a time. cars.forEach(function (car) { // The code within the following block runs only if the // current car does NOT exist in the uniqueCars list // - aka prevent duplicates if (uniqueCars.indexOf(car) === -1) { // Since we now know we haven't seen this car before, // copy it to the end of the uniqueCars list. uniqueCars.push(car); } });

이것을 즉시 재사용할 수 있도록 함수에 넣습니다.

 function deduplicate(data) { if (data.length > 0) { var result = []; data.forEach(function (elem) { if (result.indexOf(elem) === -1) { result.push(elem); } }); return result; } }

따라서 중복을 제거하기 위해 이제 이 작업을 수행합니다.

 var uniqueCars = deduplicate(cars);

deduplicate(cars) 부분 함수가 완료될 때 result 라는 이름이 됩니다.

원하는 배열의 이름을 전달하면 됩니다.


Seth Holladay

이 작업을 수행하는 가장 간단하고 빠른 (Chrome) 방법:

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

단순히 배열의 모든 항목을 살펴보고 해당 항목이 이미 목록에 있는지 테스트하고 그렇지 않은 경우 반환되는 배열로 푸시합니다.

JSBench에 따르면 이 기능은 내가 어디에서나 찾을 수 있는 기능 중 가장 빠릅니다. 자유롭게 추가할 수 있습니다.

프로토타입이 아닌 버전:

 function uniques(arr) { var a = []; for (var i=0, l=arr.length; i<l; i++) if (a.indexOf(arr[i]) === -1 && arr[i] !== '') a.push(arr[i]); return a; }

정렬

배열을 정렬해야 하는 경우 다음이 가장 빠릅니다.

 Array.prototype.sortUnique = function() { this.sort(); var last_i; for (var i=0;i<this.length;i++) if ((last_i = this.lastIndexOf(this[i])) !== i) this.splice(i+1, last_i-i); return this; }

또는 프로토타입이 아닌 경우:

 function sortUnique(arr) { arr.sort(); var last_i; for (var i=0;i<arr.length;i++) if ((last_i = arr.lastIndexOf(arr[i])) !== i) arr.splice(i+1, last_i-i); return arr; }

이것은 또한 대부분의 비 Chrome 브라우저에서 위의 방법보다 빠릅니다.


Joeytje50

["Defects", "Total", "Days", "City", "Defects"].reduce(function(prev, cur) { return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev; }, []); [0,1,2,0,3,2,1,5].reduce(function(prev, cur) { return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev; }, []);

sergeyz

ES6 세트를 사용하여 이 작업을 수행할 수 있습니다.

 var duplicatedArray = [1, 2, 3, 4, 5, 1, 1, 1, 2, 3, 4]; var uniqueArray = Array.from(new Set(duplicatedArray)); console.log(uniqueArray);

//출력은

 uniqueArray = [1,2,3,4,5];

chinmayan

마법

 a.filter(e=>!(t[e]=e in t))

O(n) 성능( new Set 보다 빠름); 우리는 당신의 배열에 가정 와 a t={} . 여기에 설명(+ Jeppe impr.)

 let t, unique= a=> ( t={}, a.filter(e=>!(t[e]=e in t)) ); // "stand-alone" version working with global t: // a1.filter((t={},e=>!(t[e]=e in t))); // Test data let a1 = [5,6,0,4,9,2,3,5,0,3,4,1,5,4,9]; let a2 = [[2, 17], [2, 17], [2, 17], [1, 12], [5, 9], [1, 12], [6, 2], [1, 12]]; let a3 = ['Mike', 'Adam','Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']; // Results console.log(JSON.stringify( unique(a1) )) console.log(JSON.stringify( unique(a2) )) console.log(JSON.stringify( unique(a3) ))


Kamil Kiełczewski

이 프로토타입 getUnique ["1",1,2,3,4,1,"foo"] ["1","2","3","4"] 반환하기 때문에 완전히 정확하지 않습니다. ["1","2","3","4"]"1" 은 문자열이고 1 은 정수입니다. 그들은 달라요.

올바른 해결책은 다음과 같습니다.

 Array.prototype.unique = function(a){ return function(){ return this.filter(a) } }(function(a,b,c){ return c.indexOf(a,b+1) < 0 });

사용:

 var foo; foo = ["1",1,2,3,4,1,"foo"]; foo.unique();

위는 ["1",2,3,4,1,"foo"] 합니다.


Gabriel Silveira

여기에서 90개 이상의 답변을 모두 살펴본 후 하나 더 들어갈 여지가 있음을 확인했습니다.

Array.includes는 "fromIndex의"이므로를 사용함으로써, 모든 반복 : 매우 편리한 번째 파라미터 갖는 filter 콜백 방법부터 배열을 검색한다 [current index] + 1 현재 필터링 항목을 포함하지 않도록 보장 조회하고 시간도 절약합니다.

 // var list = [0,1,2,2,3,'a','b',4,5,2,'a'] console.log( list.filter((v,i) => !list.includes(v,i+1)) ) // [0,1,3,"b",4,5,2,"a"]

설명:

예를 들어, 가정 할 filter 기능은 인덱스를 반복한다 2 ) 및 그 인덱스 값이 우연히 2 . includes )을 검색하는 배열 섹션은 인덱스 2( i+1 ) 이후의 모든 것입니다.

 [0, 1, 2, 2 ,3 ,'a', 'b', 4, 5, 2, 'a'] |---------------------------|

그리고 현재 필터링된 항목의 값 2 가 나머지 배열에 포함되기 때문에 필터 규칙을 무효화하는 선행 느낌표 때문에 필터링됩니다.


vsync

[...new Set(duplicates)]

이것은 가장 간단한 것으로 MDN Web Docs 에서 참조됩니다.

 const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5] console.log([...new Set(numbers)]) // [2, 3, 4, 5, 6, 7, 32]

ifelse.codes

0 은 거짓 값이기 때문입니다.

배열의 값이 0 또는 다른 거짓 값이면 this[i]


Luca Matteis

Array.prototype을 확장하거나(나쁜 습관이라고 함) jquery/underscore를 사용하지 않고 단순히 배열을 filter

마지막 항목을 유지하여:

 function arrayLastUnique(array) { return array.filter(function (a, b, c) { // keeps last occurrence return c.indexOf(a, b + 1) < 0; }); },

또는 첫 번째 발생:

 function arrayFirstUnique(array) { return array.filter(function (a, b, c) { // keeps first occurrence return c.indexOf(a) === b; }); },

글쎄, 그것은 단지 IE9+를 의미하는 javascript ECMAScript 5+일 뿐이지만, 네이티브 HTML/JS(Windows Store App, Firefox OS, Sencha, Phonegap, Titanium, ...)에서 개발하기에 좋습니다.


Cœur

이것은 많은 답변을 받았지만 내 특정 요구 사항을 해결하지 못했습니다.

많은 답변은 다음과 같습니다.

 a.filter((item, pos, self) => self.indexOf(item) === pos);

그러나 이것은 복잡한 객체의 배열에는 작동하지 않습니다.

다음과 같은 배열이 있다고 가정해 보겠습니다.

 const a = [ { age: 4, name: 'fluffy' }, { age: 5, name: 'spot' }, { age: 2, name: 'fluffy' }, { age: 3, name: 'toby' }, ];

고유한 이름을 가진 객체를 array.prototype.findIndex 대신 array.prototype.indexOf .

 a.filter((item, pos, self) => self.findIndex(v => v.name === item.name) === pos);

Dave

Prototype 프레임워크를 사용하는 경우 'for' 루프를 수행할 필요가 없습니다. 다음과 같이 http://prototypejs.org/doc/latest/language/Array/prototype/uniq/를 사용할 수 있습니다.

 var a = Array.uniq();

중복이 없는 중복 배열을 생성합니다. 고유한 배열 레코드를 계산하는 방법을 검색하는 귀하의 질문을 발견하여 uniq() size() 했고 간단한 결과가 있었습니다. ps. 제가 잘못 입력했다면 죄송합니다.

편집: 정의되지 않은 레코드를 이스케이프하려면 다음과 같이 전에 compact()

 var a = Array.compact().uniq();

Decebal

Array.prototype.getUnique = function() { var o = {}, a = [] for (var i = 0; i < this.length; i++) o[this[i]] = 1 for (var e in o) a.push(e) return a }

ephemient

이제 세트를 사용하여 중복을 제거하고 다시 배열로 변환할 수 있습니다.

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

또 다른 솔루션은 정렬 및 필터를 사용하는 것입니다.

 var names = ["Mike","Matt","Nancy", "Matt","Adam","Jenny","Nancy","Carl"]; var namesSorted = names.sort(); const result = namesSorted.filter((e, i) => namesSorted[i] != namesSorted[i+1]); console.log(result);


Krishnadas PC

배열에서 중복 ID 속성이 있는 개체를 제거해야 하는 약간 다른 문제가 있었습니다. 이것은 효과가 있었다.

 let objArr = [{ id: '123' }, { id: '123' }, { id: '456' }]; objArr = objArr.reduce((acc, cur) => [ ...acc.filter((obj) => obj.id !== cur.id), cur ], []); console.log(objArr);


shunryu111

가장 간단한 대답은 다음과 같습니다.

 const array = [1, 1, 2, 2, 3, 5, 5, 2]; const uniqueArray = [...new Set(array)]; console.log(uniqueArray); // [1, 2, 3, 5]

Sukanta Bala

추가 종속성에 문제가 없거나 이미 코드베이스에 라이브러리 중 하나가 있는 경우 LoDash(또는 Underscore)를 사용하여 배열에서 중복을 제거할 수 있습니다.

용법

코드베이스에 아직 없으면 npm을 사용하여 설치합니다.

 npm install lodash

그런 다음 다음과 같이 사용합니다.

 import _ from 'lodash'; let idArray = _.uniq ([ 1, 2, 3, 3, 3 ]); console.dir(idArray);

밖:

 [ 1, 2, 3 ]

NikeshPathania

Gabriel Silveira가 왜 그런 식으로 함수를 작성했는지 확실하지 않지만 나에게 잘 작동하고 축소 없이 작동하는 더 간단한 형식은 다음과 같습니다.

 Array.prototype.unique = function() { return this.filter(function(value, index, array) { return array.indexOf(value, index + 1) < 0; }); };

또는 CoffeeScript에서:

 Array.prototype.unique = -> this.filter( (value, index, array) -> array.indexOf(value, index + 1) < 0 )

Dan Fox

간단한 방법으로 고유한 Array 값 찾기

 function arrUnique(a){ var t = []; for(var x = 0; x < a.length; x++){ if(t.indexOf(a[x]) == -1)t.push(a[x]); } return t; } arrUnique([1,4,2,7,1,5,9,2,4,7,2]) // [1, 4, 2, 7, 5, 9]

Saravanan Rajaraman

이상하게도 이것은 이전에 제안되지 않았습니다. id )로 중복을 제거하려면 다음과 같이 할 수 있습니다.

 const uniqArray = array.filter((obj, idx, arr) => ( arr.findIndex((o) => o.id === obj.id) === idx ))

daviestar

몇 년 동안 받아 들여진 답변으로 서 있던 Rafael의 답변 을 잃어버린 것 같습니다. 이것은 혼합 유형 배열이 없는 경우 (적어도 2017년에는) 가장 성능이 좋은 솔루션이었습니다.

 Array.prototype.getUnique = function(){ var u = {}, a = []; for (var i = 0, l = this.length; i < l; ++i) { if (u.hasOwnProperty(this[i])) { continue; } a.push(this[i]); u[this[i]] = 1; } return a; }

당신이 혼합 된 형태의 배열이있는 경우, 당신은 해시 키를 직렬화 할 수 있습니다 :

 Array.prototype.getUnique = function() { var hash = {}, result = [], key; for ( var i = 0, l = this.length; i < l; ++i ) { key = JSON.stringify(this[i]); if ( !hash.hasOwnProperty(key) ) { hash[key] = true; result.push(this[i]); } } return result; }

Jason

고유 ID가 있는 객체 기반 배열의 경우 선형 복잡성으로 정렬할 수 있는 간단한 솔루션이 있습니다.

 function getUniqueArr(arr){ const mapObj = {}; arr.forEach(a => { mapObj[a.id] = a }) return Object.values(mapObj); }

Shreyansh Sharma

작업은 임의의 유형 (기본 및 비기본)으로 구성된 배열에서 고유한 배열을 가져오는 것입니다.

new Set(...) 사용에 기반한 접근 방식은 새로운 것이 아닙니다. JSON.stringify(...) , JSON.parse(...)[].map 메서드에 의해 활용됩니다. 장점은 보편성 (모든 유형의 배열에 적용 가능), 짧은 ES6 표기법 및 이 경우의 성능일 수 있습니다.

 const dedupExample = [ { a: 1 }, { a: 1 }, [ 1, 2 ], [ 1, 2 ], 1, 1, '1', '1' ] const getUniqArrDeep = arr => { const arrStr = arr.map(item => JSON.stringify(item)) return [...new Set(arrStr)] .map(item => JSON.parse(item)) } console.info(getUniqArrDeep(dedupExample)) /* [ {a: 1}, [1, 2], 1, '1' ] */


Roman

고유한 배열을 만들기 위해 개체 키를 사용하여 다음을 시도했습니다.

 function uniqueArray( ar ) { var j = {}; ar.forEach( function(v) { j[v+ '::' + typeof v] = v; }); return Object.keys(j).map(function(v){ return j[v]; }); } uniqueArray(["1",1,2,3,4,1,"foo", false, false, null,1]);

["1", 1, 2, 3, 4, "foo", false, null] 반환


rab

출처 : http:www.stackoverflow.com/questions/1960473/get-all-unique-values-in-a-javascript-array-remove-duplicates

반응형