배열에서 고유하지 않은 모든 값 (예 : 중복 / 둘 이상의 발생)을 가져옵니다.


418

중복 값이 ​​있는지 확인하려면 JavaScript 배열을 확인해야합니다. 가장 쉬운 방법은 무엇입니까? 중복 된 값이 무엇인지 찾아야합니다. 실제로 색인이나 중복 횟수가 필요하지 않습니다.

배열을 반복하고 일치하는 다른 모든 값을 확인할 수 있지만 더 쉬운 방법이 있어야합니다.

비슷한 질문 :


22
이 질문이 무엇을하는지에 대해 수년간 혼란이있는 것 같습니다. 배열의 어떤 요소가 복제되었는지 알아야했습니다. "중복 된 값이 무엇인지 찾아야합니다." 정답은 배열에서 중복을 제거해서는 안됩니다. 그것은 내가 원했던 것과 반대입니다. 독특한 요소 목록이 아닌 복제 목록입니다.
Scott Saunders

답변:


301

배열을 정렬 한 다음 실행하여 다음 (또는 이전) 인덱스가 현재와 같은지 확인할 수 있습니다. 정렬 알고리즘이 양호하다고 가정하면 O (n 2 ) 보다 작아야합니다 .

const findDuplicates = (arr) => {
  let sorted_arr = arr.slice().sort(); // You can define the comparing function here. 
  // JS by default uses a crappy string compare.
  // (we use slice to clone the array so the
  // original array won't be modified)
  let results = [];
  for (let i = 0; i < sorted_arr.length - 1; i++) {
    if (sorted_arr[i + 1] == sorted_arr[i]) {
      results.push(sorted_arr[i]);
    }
  }
  return results;
}

let duplicatedArray = [9, 9, 111, 2, 3, 4, 4, 5, 7];
console.log(`The duplicates in ${duplicatedArray} are ${findDuplicates(duplicatedArray)}`);

중복의 함수로 반환하려는 경우. 이것은 비슷한 유형의 경우입니다.

참조 : https://stackoverflow.com/a/57532964/8119511


10
"정렬 알고리즘이 좋다고 가정하면 O ^ 2보다 작아야합니다." 구체적으로 O (n * log (n)) 일 수 있습니다.
ESRogs 2016 년

83
이 스크립트는 2 개 이상의 복제본에서 잘 작동하지 않습니다 (예 :arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];
Mottie

7
@ swilliams 나는 그 지침이 사용하지 않는 것에 대해 아무 말도하지 않는다고 생각합니다 i++. 대신에 그들은 쓰지 말라고한다 j = i + +j. 다른 두 가지 IMHO. 나는 i += 1단순하고 아름다운 것보다 더 혼란 스럽다고 생각합니다. i++:)
Danilo Bargen

34
-1이 대답은 여러 수준에서 잘못되었습니다. 우선 var sorted_arr = arr.sort()은 쓸모가 없습니다 : arr.sort()원래 배열을 변경합니다 (자체적으로 문제가됩니다). 또한 요소를 버립니다. cc @dystroy 더 깨끗한 해결책은 다음과 같습니다.results = arr.filter(function(elem, pos) { return arr.indexOf(elem) == pos; })
NullUserException

24
모두 : 질문은 중복 값을 표시하지 말고 제거하지 말 것을 요청합니다. 시도하지 않은 작업을 수행하기 위해 코드를 편집하거나 중단하지 마십시오. 경고는 중복 된 값을 표시해야합니다.
Scott Saunders

205

복제본을 구상하려면 다음과 같은 훌륭한 솔루션을 시도하십시오.

function eliminateDuplicates(arr) {
  var i,
      len = arr.length,
      out = [],
      obj = {};

  for (i = 0; i < len; i++) {
    obj[arr[i]] = 0;
  }
  for (i in obj) {
    out.push(i);
  }
  return out;
}

출처 : http://dreaminginjavascript.wordpress.com/2008/08/22/eliminating-duplicates/


18
좋은 코드이지만 불행히도 내가 원하는 것을하지 않습니다.
Scott Saunders

67
위의 코드는 내 블로그입니다. 약간의 조정 만하면됩니다. 우선, arr.length와 out.length가 같은지 확인할 수 있습니다. 동일한 경우 중복 된 요소가 없습니다. 그러나 당신은 조금 더 원합니다. 듀프가 발생할 때 "캐치"를하려면 obj [arr [i]] = 0 행 이후에 배열의 길이가 증가하는지 확인하십시오. 괜찮아? :-) 멋진 단어 Raphael Montanaro에게 감사드립니다.
Nosredna

6
@MarcoDemaio : 아뇨, 왜 코드가 공백으로 작동하지 않습니까? 속성 이름에 원하는 것을 넣을 수 있습니다. 점 구문을 사용하여 공백이있는 구문에 액세스 할 수 없습니다 (파싱을 방해하는 다양한 다른 문자가있는 소품도).
Gijs

4
@Gijs : +1 당신이 맞아요. 나는 그것을 몰랐다. 그러나 객체 배열 일 때는 여전히 작동하지 않습니다.
Marco Demaio

3
이 알고리즘은 정렬 된 배열을 반환하는 부작용도 있습니다. 원하는 배열이 아닐 수도 있습니다.
비대칭

166

이것은 중복 스레드 (!)의 대답입니다.

이 항목을 작성할 때 2014-모든 예제는 for-loops 또는 jQuery입니다. Javascript에는 정렬, 매핑 및 축소와 같은 완벽한 도구가 있습니다.

중복 항목 찾기

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 duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1)

console.log(duplicates) // [ 'Nancy' ]

보다 기능적인 구문 :

@ Dmytro-Laptin은 일부 코드 코드가 제거되었다고 지적했습니다. 이것은 동일한 코드의보다 컴팩트 한 버전입니다. 일부 ES6 트릭과 고차 함수 사용 :

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

const count = names =>
  names.reduce((a, b) => ({ ...a,
    [b]: (a[b] || 0) + 1
  }), {}) // don't forget to initialize the accumulator

const duplicates = dict =>
  Object.keys(dict).filter((a) => dict[a] > 1)

console.log(count(names)) // { Mike: 1, Matt: 1, Nancy: 2, Adam: 1, Jenny: 1, Carl: 1 }
console.log(duplicates(count(names))) // [ 'Nancy' ]


1
이것이 내가 찾던 일종의 솔루션입니다. 12 개의 for-loop를 원한다면 작성하기가 매우 쉽습니다. OP의 핵심 단어는 "효율적"이었습니다.
Josh

@ChristianLandgren, 'dict'변수는 어디에 선언되어 있습니까? 아마도 'count'를 대신 사용해야합니까?
Dmytro Laptin

4
자신에 대한 오해의 소지가있는 견해를 유지하십시오 (오만 인 경우 -1). 저는 사람들이 "짧고"효율적으로 혼란스럽고 성능에 의문을 제기하지 않고 하나의 라이너를 게시하는 것에 지쳤습니다. 쇼트 프로그램과 현대 JS는 본질적으로 좋지 않습니다. "효율적"이라는 단어의 일반적인 오용 여기 . 여기에 전형적인 순진한 믿음 (다음 주석을 읽으십시오). 여기 데모 .
leaf

1
@leaf-자신의 답변에 제안을 보관하십시오. 편집 한 솔루션을 읽을 수 없으며 성능이 좋을 수도 있지만 아마도 가독성도 종종 내 의견으로는 성능보다 중요합니다. 그러나 가장 중요한 것은 이유없이 다른 사람의 코드를 제거하여 다른 사람의 코드를 제거하지 마십시오.
Christian Landgren 2016 년

1
다른 대답, 예, 다른 의견, 나는 그렇게 생각하지 않습니다.
leaf

64

배열에서 중복 값 찾기

이것은 실제로 배열에서 중복 값을 찾는 가장 짧은 방법 중 하나 여야합니다. OP에서 특별히 요청한대로 중복을 제거하지는 않지만 찾습니다 .

var input = [1, 2, 3, 1, 3, 1];

var duplicates = input.reduce(function(acc, el, i, arr) {
  if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el); return acc;
}, []);

document.write(duplicates); // = 1,3 (actual array == [1, 3])

정렬 또는 타사 프레임 워크가 필요하지 않습니다. 또한 수동 루프가 필요하지 않습니다. indexOf () (또는 더 명확하게하기 위해 : 엄격한 비교 연산자 )가 지원 하는 모든 값으로 작동 합니다.

의 때문에 것은 감소 ()같이 IndexOf () 는 적어도 IE 9이 필요합니다.


7
ES6 화살표 / 단순 / 순수 버전 :const dupes = items.reduce((acc, v, i, arr) => arr.indexOf(v) !== i && acc.indexOf(v) === -1 ? acc.concat(v) : acc, [])
ZephDavies

30

이 함수를 추가하거나 조정하여 Javascript의 Array 프로토 타입에 추가 할 수 있습니다.

Array.prototype.unique = function () {
    var r = new Array();
    o:for(var i = 0, n = this.length; i < n; i++)
    {
        for(var x = 0, y = r.length; x < y; x++)
        {
            if(r[x]==this[i])
            {
                alert('this is a DUPE!');
                continue o;
            }
        }
        r[r.length] = this[i];
    }
    return r;
}

var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,9];
var unique = arr.unique();
alert(unique);

이것이 가장 좋은 솔루션이지만 값을 반복 할 경우 IE를 망칠 수 있으므로 배열 프로토 타입에 추가하는 데주의하십시오.
Sampsa Suoninen

@RoyTinker perl도 그것들을 지원하지만, 자바 스크립트가 어떻게되는지 전혀 몰랐습니다
Luke H

1
OP가 요청한 내용을 수행하지 않고 중복을 반환합니다.
RWC

27

업데이트 됨 : 다음은 최적화 된 결합 전략을 사용합니다. 해시 O (1) 조회 시간 ( unique기본 요소 배열에서 실행 되는 것은 O (n) 임)의 이점을 얻도록 기본 조회를 최적화합니다 . 객체 조회는 반복하면서 고유 ID로 객체에 태그를 지정하여 최적화되므로 중복 객체를 식별하는 것도 항목 당 O (1)이고 전체 목록에 대해 O (n)입니다. 유일한 예외는 고정 된 항목이지만 드물고 대체는 array 및 indexOf를 사용하여 제공됩니다.

var unique = function(){
  var hasOwn = {}.hasOwnProperty,
      toString = {}.toString,
      uids = {};

  function uid(){
    var key = Math.random().toString(36).slice(2);
    return key in uids ? uid() : uids[key] = key;
  }

  function unique(array){
    var strings = {}, numbers = {}, others = {},
        tagged = [], failed = [],
        count = 0, i = array.length,
        item, type;

    var id = uid();

    while (i--) {
      item = array[i];
      type = typeof item;
      if (item == null || type !== 'object' && type !== 'function') {
        // primitive
        switch (type) {
          case 'string': strings[item] = true; break;
          case 'number': numbers[item] = true; break;
          default: others[item] = item; break;
        }
      } else {
        // object
        if (!hasOwn.call(item, id)) {
          try {
            item[id] = true;
            tagged[count++] = item;
          } catch (e){
            if (failed.indexOf(item) === -1)
              failed[failed.length] = item;
          }
        }
      }
    }

    // remove the tags
    while (count--)
      delete tagged[count][id];

    tagged = tagged.concat(failed);
    count = tagged.length;

    // append primitives to results
    for (i in strings)
      if (hasOwn.call(strings, i))
        tagged[count++] = i;

    for (i in numbers)
      if (hasOwn.call(numbers, i))
        tagged[count++] = +i;

    for (i in others)
      if (hasOwn.call(others, i))
        tagged[count++] = others[i];

    return tagged;
  }

  return unique;
}();

ES6 모음을 사용할 수있는 경우 훨씬 간단하고 훨씬 빠른 버전이 있습니다. (IE9 + 및 기타 브라우저의 경우 : https://github.com/Benvie/ES6-Harmony-Collections-Shim )

function unique(array){
  var seen = new Set;
  return array.filter(function(item){
    if (!seen.has(item)) {
      seen.add(item);
      return true;
    }
  });
}

정말? 왜 2 년 전에 해결 된 질문에 대답합니까?
르네 냄비

3
나는 또 다른 질문에 답하고 실수 로이 질문에 링크 된 누군가를 클릭하여 복제본이라고 부르고 내 대답을 복제하고 지옥을 혼란스럽게했습니다. 물건을 많이 편집합니다.


16
다른 솔루션으로 훌륭하다고 생각합니다. 주제를 오래하고 해결했는지는 중요하지 않습니다.이를 수행하는 다른 방법을 여전히 생각 해낼 수 있기 때문입니다. 컴퓨터 과학의 전형적인 문제입니다.
Emil Vikström

이것은 IE <9에서 구현되지 않은 ES5 어레이 메소드에 의존한다고 언급 할 수 있습니다.
Tim Down

24

업데이트 : 짧은 원 라이너로 복제본을 얻습니다.

[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) !== i) // [2, 4]

중복없이 배열을 얻으려면 단순히 조건을 반전하십시오.

[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) === i) // [1, 2, 3, 4]

나는 단순히 filter()아래의 오래된 대답에서 생각하지 않았다 .)


이 질문 에서 요청한대로 중복이 없는지 확인하는 것만으로도이 every()방법을 사용할 수 있습니다 .

[1, 2, 3].every((e, i, a) => a.indexOf(e) === i) // true

[1, 2, 1].every((e, i, a) => a.indexOf(e) === i) // false

참고 every()아래의 IE 8 작동하지 않습니다.


1
OP가 요청한 내용을 수행하지 않고 중복을 반환합니다.
RWC

사실, 나는 그것을 고치기 위해 대답을 업데이트했다.
Laurent Payot

왕실 솔루션! thnaks
Jeremy Piednoel

21
var a = ["a","a","b","c","c"];

a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})

이것은 작동하는 것처럼 보이지만 작동 방식을 설명하는 텍스트를 포함해야 할 것입니다.
DIMM Reaper

1
중복 값이 ​​두 번 이상 발생하면 작동하지 않습니다.
vasa

1
우아하고 간단합니다. 나는 그것을 좋아한다. 작동 방식을 알고 싶은 사람들을 위해 중복을 표시하고 제거하는 방법을 보여주는 요점을 만들었습니다. 여기 참조 : gist.github.com/jbcoder/f1c616a32ee4d642691792eebdc4257b
Josh

제위한 @TheDIMMReaper 'a'배열, 내측 필터 함수 index == 1반면self.indexOf('a') == 0
세르지 Ostrovsky

19

이것은 당신이 원하는 것을 얻을 것입니다.

function find_duplicates(arr) {
  var len=arr.length,
      out=[],
      counts={};

  for (var i=0;i<len;i++) {
    var item = arr[i];
    counts[item] = counts[item] >= 1 ? counts[item] + 1 : 1;
    if (counts[item] === 2) {
      out.push(item);
    }
  }

  return out;
}

find_duplicates(['one',2,3,4,4,4,5,6,7,7,7,'pig','one']); // -> ['one',4,7] in no particular order.


9

ES2015

//          🚩🚩   🚩                 🚩 
var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
    arr2 = [1,2,511,12,50],
    arr3 = [22],
    unique;

// Combine all the arrays to a single one
unique = arr.concat(arr2, arr3)

// create a new (dirty) Array with only the unique items
unique = unique.map((item,i) => unique.includes(item, i+1) ? item : '' )

// Cleanup - remove duplicate & empty items items 
unique = [...new Set(unique)].filter(n => n)

console.log(unique)


3 개 이상의 배열에서 고유 한 값을 찾습니다.

Array.prototype.unique = function () {
    var arr = this.sort(), i; // input must be sorted for this to work
    for( i=arr.length; i--; )
      arr[i] === arr[i-1] && arr.splice(i,1); // remove duplicate item

    return arr;
}

var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,9],
    arr2 = [1,2,511,12,50],
    arr3 = [22],
    // merge arrays & call custom Array Prototype - "unique"
    unique = arr.concat(arr2, arr3).unique();

console.log(unique);  // [22, 50, 12, 511, 2, 1, 9, 5, 8, 7, 3, 6, 4]

오래된 브라우저의 경우 arrayIndexOf에 대한 polyfill 만 있습니다.

if (!Array.prototype.indexOf){
   Array.prototype.indexOf = function(elt /*, from*/){
     var len = this.length >>> 0;

     var from = Number(arguments[1]) || 0;
     from = (from < 0) ? Math.ceil(from) : Math.floor(from);
     if (from < 0)
        from += len;

     for (; from < len; from++){
        if (from in this && this[from] === elt)
           return from;
     }
     return -1;
  };
}

"inArray"를 사용한 jQuery 솔루션 :

if( $.inArray(this[i], arr) == -1 )

추가하는 대신 Array.prototype.indexOf


Array.indexOf를 사용하여 코드를 확실히 읽을 수 있기 때문에 +1이지만 불행히도 간단한 중첩 루프를 사용하는 것보다 느립니다. FF와 같이 Array.indexOf를 구현하는 브라우저에서도 마찬가지입니다. Plz, 여기서 수행 한 테스트 ( jsperf.com/array-unique2)를 보고 의견을 알려주십시오.
마르코 데마 이오

@ shekhardesigner-답변을 업데이트했습니다. "r"은 검색 한 배열입니다.
vsync

@vsync var r = [];코드를 작동시키기 위해 초기화 해야했습니다. 그리고 매력처럼 일했습니다.
Shekhar K. Sharma

@shekhardesigner - 나는 당신이 필요하지 않은 배열의 프로토 타입 솔루션, 혼합 미안 해요 r변수
VSYNC

2
OP가 요청한 내용을 수행하지 않고 중복을 반환합니다.
RWC

8

여기 내 단순하고 한 줄 솔루션이 있습니다.

고유 한 요소를 먼저 검색하지 않고 Set를 사용하여 찾은 배열을 고유하게 만듭니다.

그래서 결국에는 중복 배열이 있습니다.

var array = [1, 2, 2, 3, 3, 4, 5, 6, 2, 3, 7, 8, 5, 22, 1, 2, 511, 12, 50, 22];

console.log([...new Set(
  array.filter((value, index, self) => self.indexOf(value) !== index))]
);


7

이것은 나의 제안이다 (ES6).

let a = [1, 2, 3, 4, 2, 2, 4, 1, 5, 6]
let b = [...new Set(a.sort().filter((o, i) => o !== undefined && a[i + 1] !== undefined && o === a[i + 1]))]

// b is now [1, 2, 4]

1
단일 발생이 undefined중복 임을보고합니다 .
Dem Pilafian

1
@DemPilafian 감사합니다, 업데이트
lukaszkups

6
var a = [324,3,32,5,52,2100,1,20,2,3,3,2,2,2,1,1,1].sort();
a.filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});

또는 배열의 프로토 타입 체인에 추가 될 때

//copy and paste: without error handling
Array.prototype.unique = 
   function(){return this.sort().filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});}

여기를 참조하십시오 : https://gist.github.com/1305056


1
필터 함수는 요소 자체가 아닌 true 또는 false를 반환해야합니다. 0을 포함하는 배열을 필터링하면 반환되지 않았습니다.
mflodin

또한 i&&배열의 범위를 벗어나는 것을 피 한다고 가정 하지만 정렬 된 배열의 첫 번째 요소는 포함되지 않습니다. 귀하의 예에서는 1결과 배열 이 없습니다 . IE는 return i&&v!==o[i-1]?v:0;해야한다return v!==o[i-1];
mflodin

6

es6 객체 구조 제거를 통한 빠르고 우아한 방법

O (n) (배열에서 1 회 반복)으로 실행되며 2 번 이상 나타나는 값을 반복하지 않습니다

const arr = ['hi', 'hi', 'hi', 'bye', 'bye', 'asd']
const {
  dup
} = arr.reduce(
  (acc, curr) => {
    acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1
    if (acc.items[curr] === 2) acc.dup.push(curr)
    return acc
  }, {
    items: {},
    dup: []
  },
)

console.log(dup)
// ['hi', 'bye']


5

내가 생각할 수있는 가장 간단한 해결책은 다음과 같습니다.

    const arr = [-1, 2, 2, 2, 0, 0, 0, 500, -1, 'a', 'a', 'a']

    const filtered = arr.filter((el, index) => arr.indexOf(el) !== index)
    // => filtered = [ 2, 2, 0, 0, -1, 'a', 'a' ]

    const duplicates = [...new Set(filtered)]

    console.log(duplicates)
    // => [ 2, 0, -1, 'a' ]

그게 다야.

노트 :

  1. 0, 문자열 및 음수를 포함한 모든 숫자와 함께 작동 합니다. 예 -1- 관련 질문 : JavaScript 배열에서 모든 고유 값 가져 오기 (중복 제거)

  2. 원본 배열 arr이 유지됩니다 ( filter원본을 수정하는 대신 새 배열을 반환 함)

  3. filtered배열을 포함 하는 모든 중복; 또한 하나 이상의 동일한 값을 포함 할 있습니다 (예 : 필터링 된 배열은 여기입니다 [ 2, 2, 0, 0, -1, 'a', 'a' ])

  4. 당신이 얻을하려는 경우 에만 당신은 사용할 수 있습니다 (같은 값을 여러 개 중복 싶지 않아) 중복되는 값을 [...new Set(filtered)](ES6는 객체가 세트 에만 고유 한 값을 저장할 수 있습니다)

도움이 되었기를 바랍니다.


5

최단 바닐라 JS :

[1,1,2,2,2,3].filter((v,i,a) => a.indexOf(v) !== i) // [1, 2, 2]

4

매우 가볍고 쉬운 방법은 다음과 같습니다.

var codes = dc_1.split(',');
var i = codes.length;
while (i--) {
  if (codes.indexOf(codes[i]) != i) {
    codes.splice(i,1);
  }
}

가장 좋은 답변입니다. 그리고 사용자가 중복 요소 배열을 원할 경우 @brandon 코드를 업데이트했습니다. var i = codes .length; var duplicate = []; while (i--) {if (codes .indexOf (codes [i])! = i) {if (duplicate.indexOf (codes [i]) === -1) {duplicate.push (arr [i]) ; } codes.splice (i, 1); }}
Himanshu Shekhar

4

ES6 (또는 Babel 또는 Typescipt 사용)을 사용하면 다음을 수행 할 수 있습니다.

var duplicates = myArray.filter(i => myArray.filter(ii => ii === i).length > 1);

https://es6console.com/j58euhbt/


나는 독립적으로 동일한 구문을 사용했으며 이것을 찾았을 때 솔루션으로 추가하려고했습니다. 아마도 가장 경제적이지는 않지만 간단합니다.
nize

4

ES6 구문의 간단한 코드 (복제 된 정렬 된 배열 반환) :

let duplicates = a => {d=[]; a.sort((a,b) => a-b).reduce((a,b)=>{a==b&&!d.includes(a)&&d.push(a); return b}); return d};

사용하는 방법:

duplicates([1,2,3,10,10,2,3,3,10]);

1
.filter ()는 훨씬 간단합니다
tocqueville

4

짧막 한 농담

var arr = [9,1,2,4,3,4,9]
console.log(arr.filter((ele,indx)=>indx!==arr.indexOf(ele))) //get the duplicates
console.log(arr.filter((ele,indx)=>indx===arr.indexOf(ele))) //remove the duplicates


무엇을 않는 indx!첫 번째 예를 들어합니까?
saylestyler

1
@saylestyler Hehe, 이것은 indx !== ...-엄격한 불평등을 의미 합니다.
Daria

객체 배열에만 추가result.filter((ele,indx) => indx !== result.map(e => e.name).indexOf(ele.name));
x-magix

4

이 답변은 도움이 될 수도 있습니다 .js reduce operator / method 를 사용 하여 배열에서 중복 을 제거 합니다.

const result = [1, 2, 2, 3, 3, 3, 3].reduce((x, y) => x.includes(y) ? x : [...x, y], []);

console.log(result);


3
우리는 이제 new Set([1, 2, 2, 3, 3, 3, 3])중복을 제거 할 수 있습니다
kimbaudi

3

다음 함수 (이미 언급 된 removeDuplicates 함수의 변형)는 입력 [ "test", "test2", "test2", 1, 1, 1, 2에 대해 test2,1,7,5를 반환하는 트릭을 수행하는 것으로 보입니다. , 3, 4, 5, 6, 7, 7, 10, 22, 43, 1, 5, 8]

JavaScript 배열은 거의 모든 것을 담을 수 있기 때문에 대부분의 다른 언어보다 JavaScript에서이 문제가 익숙하지 않습니다. 정렬을 사용하는 솔루션은 적절한 정렬 기능을 제공해야 할 수도 있습니다. 아직 해당 경로를 시도하지 않았습니다.

이 특정 구현은 (적어도) 문자열과 숫자에 적용됩니다.

function findDuplicates(arr) {
    var i,
        len=arr.length,
        out=[],
        obj={};

    for (i=0;i<len;i++) {
        if (obj[arr[i]] != null) {
            if (!obj[arr[i]]) {
                out.push(arr[i]);
                obj[arr[i]] = 1;
            }
        } else {
            obj[arr[i]] = 0;            
        }
    }
    return out;
}

3

ES5 전용 (즉, IE8 이하의 경우 filter () polyfill이 필요함) :

var arrayToFilter = [ 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3 ];

arrayToFilter.
    sort().
    filter( function(me,i,arr){
       return (i===0) || ( me !== arr[i-1] );
    });

나는이 간단한 해결책을 좋아한다. 그러나 중복을 원할 경우 먼저 해당 중복을 찾은 다음 중복 목록을 고유하게 만들어야합니다. [0, 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3] .sort (). filter (function (me, i, arr) {return (i! == 0 ) && (me == arr [i-1]);}). filter (function (me, i, arr) {return (i === 0) || (me! == arr [i-1]) ;});
Greg

3

var arr = [2, 1, 2, 2, 4, 4, 2, 5];

function returnDuplicates(arr) {
  return arr.reduce(function(dupes, val, i) {
    if (arr.indexOf(val) !== i && dupes.indexOf(val) === -1) {
      dupes.push(val);
    }
    return dupes;
  }, []);
}

alert(returnDuplicates(arr));

이 함수 는 정렬 단계를 피하고 reduce () 메소드를 사용하여 중복이 존재하지 않는 경우 중복을 새 배열로 푸시합니다.


3

이것은 아마도 가장 많은 기능보다 10 배나 빠른 배열에서 복제본을 영구적으로 제거하는 가장 빠른 방법 중 하나 일 것입니다 .

function toUnique(a,b,c){//array,placeholder,placeholder
 b=a.length;
 while(c=--b)while(c--)a[b]!==a[c]||a.splice(c,1)
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];
toUnique(array);
console.log(array);
  1. 테스트 : http://jsperf.com/wgu
  2. 데모 : http://jsfiddle.net/46S7g/
  3. 더 : https://stackoverflow.com/a/25082874/2450730

위의 코드를 읽을 수없는 경우 자바 스크립트 책을 읽거나 짧은 코드에 대한 설명을 참조하십시오. https://stackoverflow.com/a/21353032/2450730

편집 주석에서 언급 했듯이이 함수는 고유 한 배열을 반환하지만 질문은 중복 항목을 찾도록 요청합니다. 이 경우이 함수를 간단하게 수정하면 복제본을 배열로 푸시 한 다음 이전 함수를 사용 toUnique하여 복제본의 복제본을 제거 할 수 있습니다.

function theDuplicates(a,b,c,d){//array,placeholder,placeholder
 b=a.length,d=[];
 while(c=--b)while(c--)a[b]!==a[c]||d.push(a.splice(c,1))
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];

toUnique(theDuplicates(array));

7
"위의 코드를 읽을 수 없다면, 자바 스크립트 책을 읽어보십시오"이 답변에는 코드 골프가 너무 많습니다. a, b, c와 같은 변수의 이름을 지정하면 코드를 읽기가 어렵습니다. 중괄호를 잊어 버리면 더욱 악화됩니다.
River Williamson

내 답변의 대부분은 성능과 공간 절약 (다른 솔루션이 이미 게시되어 있음)을 기반으로합니다 ... 공격이 마음에 들지 않으면 ... 다른 방법으로 자바 스크립트를 배우거나 js 책을 읽거나 jquery를 사용하십시오 ... 간단한 솔루션을 검색하면 더 많은 답변을 얻을 수 있습니다. 정말로 무언가를 배우고 싶다면 문자 당 코드 문자를 설명하게되어 기쁩니다. 귀하의 의견에 실제 질문이 표시되지 않으므로 귀하는 단지 내 답변을 공감할 동기를 찾고 있다고 생각합니다 .... 계속 ... 나는 그것에 아무런 문제가 없습니다. 실제 질문을하거나 내 코드에서 작동하지 않는 것을 말하십시오.
cocco

9
코드에는 기술적으로 잘못된 것이 없습니다. 즉, 변수 a, b, c, d 등의 이름을 지정하고 체인 while 루프를 사용하면 코드를 읽기가 어렵습니다. 따라서 코드는 아무것도 가르치지 않습니다.
River Williamson

3

"includes"를 사용하여 요소가 이미 존재하는지 테스트하십시오.

var arr = [1, 1, 4, 5, 5], darr = [], duplicates = [];

for(var i = 0; i < arr.length; i++){
  if(darr.includes(arr[i]) && !duplicates.includes(arr[i]))
    duplicates.push(arr[i])
  else
    darr.push(arr[i]);
}

console.log(duplicates);
<h3>Array with duplicates</h3>
<p>[1, 1, 4, 5, 5]</p>
<h3>Array with distinct elements</h3>
<p>[1, 4, 5]</p>
<h3>duplicate values are</h3>
<p>[1, 5]</p>


코드는 별개의 요소를 돌려 주지만 주어진 결과로 이어지지는 않습니다. 정확한 코드를 입력하십시오.
RWC

3

ES6은 기본적으로 중복을 허용하지 않는 배열 인 Set 데이터 구조를 제공합니다. Set 데이터 구조를 사용하면 배열에서 중복을 찾을 수있는 매우 쉬운 방법이 있습니다 (하나의 루프 만 사용).

여기 내 코드가 있습니다

function findDuplicate(arr) {
var set = new Set();
var duplicates = new Set();
  for (let i = 0; i< arr.length; i++) {
     var size = set.size;
     set.add(arr[i]);
     if (set.size === size) {
         duplicates.add(arr[i]);
     }
  }
 return duplicates;
}

3

방금 배열 필터를 사용하여이를 달성하는 간단한 방법을 알아 냈습니다.

    var list = [9, 9, 111, 2, 3, 4, 4, 5, 7];
    
    // Filter 1: to find all duplicates elements
    var duplicates = list.filter(function(value,index,self) {
       return self.indexOf(value) !== self.lastIndexOf(value) && self.indexOf(value) === index;
    });
    
    console.log(duplicates);


3

논리를 따르는 것이 더 쉽고 빠릅니다.

// @Param:data:Array that is the source 
// @Return : Array that have the duplicate entries
findDuplicates(data: Array<any>): Array<any> {
        return Array.from(new Set(data)).filter((value) => data.indexOf(value) !== data.lastIndexOf(value));
      }

장점 :

  1. 한 줄 : -P
  2. 모든 내장 데이터 구조로 효율성 향상
  3. 더 빠른

논리 설명 :

  1. 모든 중복 항목을 제거하도록 설정으로 변환
  2. 설정된 값을 반복
  3. 소스 배열에서 각 설정 값을 점검 할 때 "첫 번째 색인 값이 마지막 색인과 같지 않습니다"==> 조건을 확인하십시오.

참고 : map () 및 filter () 메서드는 효율적이고 빠릅니다.


1
이것을 테스트했습니다 ... 매우 빠릅니다. 그리고 그것은 말이됩니다 .. 내가 그것에 대해 생각하길 바래
Michael Rhema
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.