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

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

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

비슷한 질문 :



답변

배열을 정렬 한 다음 실행하여 다음 (또는 이전) 인덱스가 현재와 같은지 확인할 수 있습니다. 정렬 알고리즘이 양호하다고 가정하면 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


답변

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

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/


답변

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

이 항목을 작성할 때 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' ]


답변

배열에서 중복 값 찾기

이것은 실제로 배열에서 중복 값을 찾는 가장 짧은 방법 중 하나 여야합니다. 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이 필요합니다.


답변

이 함수를 추가하거나 조정하여 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);


답변

업데이트 됨 : 다음은 최적화 된 결합 전략을 사용합니다. 해시 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;
    }
  });
}


답변

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

[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 작동하지 않습니다.