질문자 :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), 즉, 네이티브 메소드를 지원하지 않는 filter
와 indexOf
당신을위한 MDN 문서의 작업 방법 찾을 수 있습니다 필터 와 같이 IndexOf를 .
값의 마지막 항목을 유지하려면 indexOf
를 lastIndexOf
간단히 바꾸십시오.
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))
TLindigES6/ES2015에 대한 업데이트된 답변 : Set 및 Spread 연산자를 사용하면 ( le-m 덕분에) 한 줄 솔루션은 다음과 같습니다.
let uniqueItems = [...new Set(items)]
어떤 반환
[4, 5, 6, 3, 2, 23, 1]
A.T.4가지 가능한 솔루션에 대한 모든 답변을 나눕니다.
- 객체
{ }
를 사용하여 중복 방지 - 도우미 배열 사용
[ ]
-
filter + indexOf
- 보너스! 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 Makhrovunderscore.js를 사용할 수도 있습니다.
console.log(_.uniq([1, 2, 1, 3, 1, 4]));
<script src="http://underscorejs.org/underscore-min.js"></script>
다음을 반환합니다.
[1, 2, 3, 4]
kornfridgeOne 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; }, []);
sergeyzES6 세트를 사용하여 이 작업을 수행할 수 있습니다.
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.codes0
은 거짓 값이기 때문입니다.
배열의 값이 0 또는 다른 거짓 값이면 this[i]
Luca MatteisArray.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);
DavePrototype 프레임워크를 사용하는 경우 'for' 루프를 수행할 필요가 없습니다. 다음과 같이 http://prototypejs.org/doc/latest/language/Array/prototype/uniq/를 사용할 수 있습니다.
var a = Array.uniq();
중복이 없는 중복 배열을 생성합니다. 고유한 배열 레코드를 계산하는 방법을 검색하는 귀하의 질문을 발견하여 uniq()
size()
했고 간단한 결과가 있었습니다. ps. 제가 잘못 입력했다면 죄송합니다.
편집: 정의되지 않은 레코드를 이스케이프하려면 다음과 같이 전에 compact()
var a = Array.compact().uniq();
DecebalArray.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 ]
NikeshPathaniaGabriel 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