Мне нужно проверить массив JavaScript на наличие дубликатов значений. Какой самый простой способ сделать это? Мне просто нужно найти дублирующиеся значения - мне не нужны их индексы или сколько раз они дублируются.
Я знаю, что могу пройтись по массиву и проверить все остальные значения на совпадение, но кажется, что должен быть более простой способ.
Вы можете отсортировать массив, а затем пробежаться по нему и посмотреть, совпадает ли следующий (или предыдущий) индекс с текущим. При условии, что ваш алгоритм сортировки хорош, это должно быть меньше, чем O(n2):
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var 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)
var results = [];
for (var i = 0; i < sorted_arr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
console.log(results);
В случае, если вы хотите вернуть как функцию для дубликатов. Это для аналогичного случая.
Если вы хотите, чтобы elimate дубликаты, попробуйте это отличное решение:
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 г. - все примеры были для петель или jQuery. В JavaScript есть отличный инструмент для этого: сортировка, map и reduce.
в
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' ]
в
@Дмитро-Laptin указал быть удален некоторый код, код. Это более компактная версия этого же кодекса. Используя некоторые ЕС6 трюков и функций высшего порядка:
в
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' ]
в
Это должно быть один из самых коротких путей, чтобы найти повторяющиеся значения в массиве. Как просили в ОП, не удалить дубликаты, но не находит их.
в
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.
Вы можете добавить эту функцию или подправить ее и добавить к прототипу Array в Javascript'е:
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) время поиска (работает только на массив примитивов О(П)). Объект поиска оптимизированы объекты пометки с уникальным идентификатором, в то время как перебора, так выявляются повторяющиеся объекты и O(1) за штуку и o(n) для всего списка. Единственное исключение-предметы, которые заморожены, но это редко и нейтрализация обеспечивается использованием массива и 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;
}
});
}
var a = ["a","a","b","c","c"];
a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})
Это должно получить вас, что вы хотите, только дубликаты.
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.
Обновлено: короткие один-лайнер, чтобы получить дубликаты:
Яш [1, 2, 2, 4, 3, 4].фильтр((Е, I, а) => а.метод indexOf(е) !== я) // [2, 4]
Чтобы получить массив без дубликатов просто инвертировать условие:
Яш [1, 2, 2, 4, 3, 4].фильтр((Е, I, а) => а.метод indexOf(е) === я) // [1, 2, 3, 4]
Я просто не думаю о `фильтр () в мой старый ответ ниже ;)
Когда все, что вам нужно, это проверить, что нет никаких дубликатов, как предложено в этот вопрос вы можете использовать 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
Обратите внимание, что в <код>У каждой()</код> не't работа для IE 8 и ниже.
используя underscore.js
function hasDuplicate(arr){
return (arr.length != _.uniq(arr).length);
}
Вот мое простое и одно решение.
Его поиски не уникальные элементы первого, затем нашли такие уникальные с использованием набора.
Итак, мы имеем массив дубликатов в конце концов.
в
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))]
);
в
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
Это мое предложение (ЕС6):
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]
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]
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 и quot##;:
if( $.inArray(this[i], arr) == -1 )
в
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);
в
вместо добавления 'массив.прототип.метод indexOf'
Быстрый и элегантный способ использования объекта ЕС6 деструктурируется и сокращения
Он работает за o(Н) (1 итерация по массиву) и doesn'т повторить значений, которые появляются более чем в 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']
в
Здесь'ы самое простое решение, я мог думать:
`` константный Арр = [-1, 2, 2, 2, 0, 0, 0, 500, -1, 'Это', 'Это', 'Это']
константный отфильтрованы = Арр.фильтр((Эль, индекс) => аранж.метод indexOf(Эль) !== индекса) // => процеживают = [ 2, 2, 0, 0, -1, 'в', 'Это' ]
константный дубликаты = [...новый набор(фильтрованный)]
консоль.журнал(дубликатов) // => [ 2, 0, -1, 'Это' ] ``
Что's оно.
Примечание:
Он работает с любой цифры, в том числе 0
, строки и отрицательные числа например: -1
-
Вопрос: https://stackoverflow.com/questions/1960473
Исходный массив Арр
сохраняется ("фильтр" возвращает новый массив, а не изменять оригинал)
В отфильтрована
массив содержит все дубликатов; он может также содержать более 1 одинакового достоинства (например, наш отфильтрованный массив здесь[ 2, 2, 0, 0, -1, 'Это', 'Это' ]
)
Если вы хотите сделать только ценности, которые дублируются (вы не'т хотим, чтобы несколько повторений с тем же значением), вы можете использовать [...новый набор(фильтрованный)]
(ЕС6 есть объект комплект, которая может хранить только уникальные значения)
Надеюсь, что это помогает.
Простой код с синтаксисом ЕС6 (возвращать отсортированный массив дубликатов):
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]);
Вот очень легкий и простой способ:
var codes = dc_1.split(',');
var i = codes.length;
while (i--) {
if (codes.indexOf(codes[i]) != i) {
codes.splice(i,1);
}
}
С ЕС6 (или с помощью Бабеля или Typescipt) вы можете просто сделать:
var duplicates = myArray.filter(i => myArray.filter(ii => ii === i).length > 1);
Следующие функции (вариация eliminateDuplicates функция уже упоминалось), кажется, сделать трюк, возвращаясь test2,в 1,7,5 для ввода [на"тест" и "Ну 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;
}