Получить все неуникальные значения (т.е. дубликаты / более одного вхождения) в массиве - PullRequest
370 голосов
/ 08 мая 2009

Мне нужно проверить массив JavaScript, чтобы увидеть, есть ли какие-либо повторяющиеся значения. Какой самый простой способ сделать это? Мне просто нужно выяснить, что такое дублированные значения - мне не нужны их индексы или сколько раз они дублируются.

Я знаю, что могу перебрать массив и проверить все остальные значения на совпадение, но, похоже, должен быть более простой способ. Есть идеи? Спасибо!

Подобный вопрос:

Ответы [ 73 ]

2 голосов
/ 16 января 2013
var input = ['a', 'b', 'a', 'c', 'c'],
    duplicates = [],
    i, j;
for (i = 0, j = input.length; i < j; i++) {
  if (duplicates.indexOf(input[i]) === -1 && input.indexOf(input[i], i+1) !== -1) {
    duplicates.push(input[i]);
  }
}

console.log(duplicates);
2 голосов
/ 06 мая 2011

Я предпочитаю функциональный способ сделать это.

function removeDuplicates(links) {
    return _.reduce(links, function(list, elem) { 
        if (list.indexOf(elem) == -1) {
            list.push(elem);
        }   
        return list;
    }, []);
}

Используется подчеркивание, но в массиве есть функция reduce, также

2 голосов
/ 06 февраля 2016

Для решения вышеописанного в O (n) времени сложность (без сортировки).

var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];

var obj={};

for(var i=0;i<arr.length;i++){
    if(!obj[arr[i]]){
        obj[arr[i]]=1;
    } else {
        obj[arr[i]]=obj[arr[i]]+1;
    }
}
var result=[]
for(var key in obj){
    if(obj[key]>1){
        result.push(Number(key)) // change this to result.push(key) to find duplicate strings in an array
    }
}

console.log(result)
2 голосов
/ 05 апреля 2018

один лайнер

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
2 голосов
/ 09 мая 2009

Просто чтобы добавить некоторые теории к вышесказанному.

Нахождение дубликатов имеет нижнюю границу O (n * log (n)) в модели сравнения. Поэтому теоретически вы не можете сделать ничего лучше, чем сначала отсортировать, а затем пройти список последовательно удаляя любые найденные дубликаты.

Если вы хотите найти дубликаты в линейном (O (n)) ожидаемом времени, вы можете хэшировать каждый элемент списка; если есть столкновение, удалите / пометьте его как дубликат, и продолжить.

2 голосов
/ 20 августа 2016
function GetDuplicates(arr) {
    var i = 0, m = [];
    return arr.filter(function (n) {
        return !m[n] * ~arr.indexOf(n, m[n] = ++i);
    });
}
1 голос
/ 02 августа 2015

Аналогично нескольким другим ответам, но я использовал forEach(), чтобы сделать его немного красивее:

function find_duplicates(data) {

    var track = {};
    var duplicates = [];

    data.forEach(function (item) {
        !track[item] ? track[item] = true : duplicates.push(item);
    });

    return duplicates;
}

Если значение дублируется более одного раза, возвращаются все его дубликаты, например:

find_duplicates(['foo', 'foo', 'bar', 'bar', 'bar']);
// returns ['foo', 'bar', 'bar']

Это может быть то, что вы хотите, в противном случае вам просто нужно следовать "уникальной" фильтрации.

1 голос
/ 08 апреля 2013

Еще один способ с использованием подчеркивания. Numbers - исходный массив, и dupes имеет возможные повторяющиеся значения.

var itemcounts = _.countBy(numbers, function (n) { return n; });
var dupes = _.reduce(itemcounts, function (memo, item, idx) {
    if (item > 1)
        memo.push(idx);
    return memo;
}, []);
1 голос
/ 28 ноября 2018

Магия

a.filter(( t={}, e=>!(1-(t[e]=++t[e]|0)) )) 

O (n) производительность ; мы предполагаем, что ваш массив находится в a, и он содержит элементы, которые могут быть преобразованы .toString() уникальным способом (что в JS сделано в t[e]), например, numbers = [4,5,4], strings = [" aa "," bb "," aa "], arraysNum = [[1,2,3], [43,2,3], [1,2,3]]. Пояснение здесь , уникальные значения здесь

var a1 = [[2, 17], [2, 17], [2, 17], [1, 12], [5, 9], [1, 12], [6, 2], [1, 12]];
var a2 = ['Mike', 'Adam','Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl'];
var a3 = [5,6,4,9,2,3,5,3,4,1,5,4,9];

let nd = (a) => a.filter((t={},e=>!(1-(t[e]=++t[e]|0)))) 


// Print
let c= x => console.log(JSON.stringify(x));             
c( nd(a1) );
c( nd(a2) );
c( nd(a3) );
1 голос
/ 20 ноября 2017

Это одно из простых решений ES5, о которых я мог подумать -

function duplicates(arr) {
  var duplicatesArr = [],
      uniqueObj = {};

  for (var i = 0; i < arr.length; i++) {
    if( uniqueObj.hasOwnProperty(arr[i]) && duplicatesArr.indexOf( arr[i] ) === -1) {
      duplicatesArr.push( arr[i] );
    }
    else {
      uniqueObj[ arr[i] ] = true;
    }
  }

  return duplicatesArr;
}
/* Input Arr: [1,1,2,2,2,1,3,4,5,3] */
/* OutPut Arr: [1,2,3] */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...