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

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

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

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

Ответы [ 73 ]

6 голосов
/ 22 октября 2011
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;});

или при добавлении в prototyp.chain массива

//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

6 голосов
/ 03 декабря 2009

Поиск уникальных значений из 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],
    unique = arr.concat(arr2, arr3).unique();

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

Просто полифил для массива indexOf для старых браузеров:

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;
  };
}

Решение jQuery с использованием inArray:

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

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);

вместо добавления Array.prototype.indexOf

6 голосов
/ 13 августа 2018

Вот мое простое и однострочное решение.

Сначала он ищет не уникальные элементы, а затем делает найденный массив уникальным с помощью 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))]
);
5 голосов
/ 23 мая 2018

Быстрый и элегантный способ с использованием деструктуризации объектов 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 голосов
/ 17 октября 2018

Это мое предложение (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]
4 голосов
/ 17 июля 2017

С ES6 (или с помощью Babel или Typescipt) вы можете просто сделать:

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

https://es6console.com/j58euhbt/

4 голосов
/ 19 сентября 2017

Простой код с синтаксисом 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]);
3 голосов
/ 09 мая 2009

Следующая функция (уже упоминавшаяся разновидность функции deleDuplicates), похоже, добилась цели, возвращая test2,1,7,5 для ввода ["test", "test2", "test2", 1, 1, 1, 2, 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 голосов
/ 03 ноября 2015

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));

Эта функция избегает этапа сортировки и использует метод redu () для отправки дубликатов в новый массив, если он еще не существует в нем.

3 голосов
/ 12 августа 2016

Использование «include» для проверки того, что элемент уже существует.

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...