У меня есть объект, который содержит массив объектов.
things = new Object();
things.thing = new Array();
things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});
Мне интересно, каков наилучший способ удалить дубликаты объектов из массива. Так, например, вещи. Все станет ...
{place:"here",name:"stuff"},
{place:"there",name:"morestuff"}
javascript
arrays
object
duplicates
Travis
источник
источник
aaaaa.aaaa.push(...)
:)Ответы:
Примитивный метод будет:
источник
Как насчет
es6
магии?Ссылочный URL
Более общее решение будет:
Пример Stackblitz
источник
things.thing = things.thing.filter((thing, index, self) => self.findIndex(t => t.place === thing.place && t.name === thing.name) === index)
const uniqueArray = arrayOfObjects.filter((object,index) => index === arrayOfObjects.findIndex(obj => JSON.stringify(obj) === JSON.stringify(object)));
jsfiddle.net/x9ku0p7L/28Если вы можете использовать библиотеки Javascript, такие как подчеркивание или lodash, я рекомендую взглянуть на
_.uniq
функцию в их библиотеках. Отlodash
:По сути, вы передаете массив, который здесь является литералом объекта, и передаете атрибут, с которым вы хотите удалить дубликаты, в исходном массиве данных, например так:
ОБНОВЛЕНИЕ : Lodash теперь представил
.uniqBy
также.источник
uniqBy
вместоuniq
, например,_.uniqBy(data, 'name')
... документацию: lodash.com/docs#uniqByУ меня было точно такое же требование, чтобы удалить дубликаты объектов в массиве на основе дубликатов в одном поле. Я нашел код здесь: Javascript: удаление дубликатов из массива объектов
Поэтому в моем примере я удаляю любой объект из массива, который имеет дублирующееся строковое значение licenseNum.
Результаты:
uniqueArray - это:
источник
for(var i in array) { if(array[i][prop]){ //valid lookupObject[array[i][prop]] = array[i]; } else { console.log('falsy object'); } }
for (let i in originalArray) { if (lookupObject[originalArray[i]['id']] === undefined) { newArray.push(originalArray[i]); } lookupObject[originalArray[i]['id']] = originalArray[i]; }
Самый короткий лайнер для ES6 +
Найти уникальные
id
в массиве.Уникальный по нескольким свойствам (
place
иname
)Уникальный по всем свойствам (это будет медленно для больших массивов)
Сохраните последнее вхождение.
источник
Один лайнер, используя Set
Объяснение:
new Set(myData.map(JSON.stringify))
создает набор объект используя строковые элементы myData.источник
Используя ES6 + в одной строке, вы можете получить уникальный список объектов по ключу:
Это может быть помещено в функцию:
Вот рабочий пример:
Как это работает
Сначала массив переопределяется таким образом, чтобы его можно было использовать в качестве входных данных для карты.
что означает, что каждый элемент массива будет преобразован в другой массив с 2 элементами; выбранный ключ в качестве первого элемента и весь исходного элемента в качестве второго элемента, это называется запись (напр. , запись массива , Записи на карте ). А вот официальный документ с примером, показывающим, как добавить записи массива в конструкторе Map.
Пример , когда ключ место :
Во-вторых, мы передаем этот модифицированный массив конструктору Map, и здесь происходит волшебство. Карта удалит дублирующиеся значения ключей, сохраняя только последнее вставленное значение того же ключа. Примечание . Карта сохраняет порядок вставки. ( проверьте разницу между картой и объектом )
В-третьих, мы используем значения карты для извлечения оригинальных элементов, но на этот раз без дубликатов.
И последнее - добавить эти значения в новый новый массив, чтобы он мог выглядеть как исходная структура и вернуть это:
источник
id
. Вопрос требует, чтобы весь объект был уникальным во всех областях, таких какplace
иname
Вот еще один вариант сделать это с помощью итерационных методов Array, если вам нужно сравнение только по одному полю объекта:
источник
один лайнер здесь
источник
Если вы можете ждать устранения дубликатов до тех пор, пока не завершатся все добавления, типичный подход состоит в том, чтобы сначала отсортировать массив, а затем удалить дубликаты. Сортировка избегает подхода N * N сканирования массива для каждого элемента, когда вы проходите через них.
Функция «устранить дубликаты» обычно называется уникальной или уникальной . Некоторые существующие реализации могут объединять два этапа, например, uniq прототипа
В этом посте есть несколько идей, которые можно попробовать (и некоторые, которых следует избегать :-)), если в вашей библиотеке их еще нет ! Лично я считаю это самым прямым:
источник
function(_a,_b){return _a.a===_b.a && _a.b===_b.b;}
то массив не будет отсортирован.Самый простой способ это использовать
filter
:источник
id
. Вопрос требует, чтобы весь объект был уникальным во всех областях, таких какplace
иname
Это общий способ сделать это: вы передаете функцию, которая проверяет, считаются ли два элемента массива равными. В этом случае сравниваются значения
name
иplace
свойства двух сравниваемых объектов.ES5 ответ
Оригинальный ответ ES3
источник
Добавить еще один в список. Использование ES6 и
Array.reduce
сArray.find
.В этом примере выполняется фильтрация объектов на основе
guid
свойства.Расширение этого, чтобы позволить выбор свойства и сжать его в один лайнер:
Чтобы использовать его, передайте массив объектов и имя ключа, для которого вы хотите дедуплицировать, в виде строкового значения:
источник
Вы также можете использовать
Map
:Полный образец:
Результат:
источник
Черт, дети, давайте раздавим эту штуку, почему бы и нет?
источник
id
. Вопрос требует, чтобы весь объект был уникальным во всех областях, таких какplace
иname
place
иname
сегодня. Любой, кто читает эту ветку, ищет оптимальный способ дедупликации списка объектов, и это компактный способ сделать это.Решение TypeScript
Это удалит дубликаты объектов, а также сохранит типы объектов.
источник
принимая во внимание
lodash.uniqWith
источник
Другой вариант - создать пользовательскую функцию indexOf, которая сравнивает значения выбранного вами свойства для каждого объекта и заключает его в функцию сокращения.
источник
lodash.isequal
пакетом npm в качестве облегченного компаратора объектов для выполнения уникальной фильтрации массива ... например, отдельного массива объектов. Просто поменялся местамиif (_.isEqual(a[i], b)) {
вместо того, чтобы искать @ единственное свойствоОднострочник с использованием ES6 и
new Map()
.Подробности:-
.map()
в списке данных и преобразование каждого отдельного объекта в[key, value]
массив пар (длина = 2), первый элемент (ключ) будетstringified
версия объекта, а второй (значение) будетobject
сам по себе.new Map()
ключу будет иметьstringified
объект как объект, и любое добавление того же ключа приведет к переопределению уже существующего ключа..values()
даст MapIterator со всеми значениями в карте (obj
в нашем случае)spread ...
оператор, чтобы дать новый массив со значениями из предыдущего шага.источник
Вот решение для es6, где вы хотите сохранить только последний элемент. Это решение является функциональным и соответствует стилю Airbnb.
источник
removeDuplicates () принимает массив объектов и возвращает новый массив без каких-либо дубликатов объектов (на основе свойства id).
Ожидаемый результат:
Сначала мы устанавливаем значение переменной uniq в пустой объект.
Далее мы фильтруем массив объектов. Фильтр создает новый массив со всеми элементами, которые проходят тест, реализованный предоставленной функцией.
Выше мы используем функцию короткого замыкания &&. Если левая часть && имеет значение true, тогда она возвращает значение справа от &&. Если левая сторона ложна, она возвращает то, что находится слева от &&.
Для каждого объекта (obj) мы проверяем uniq для свойства, называемого значением obj.id (в этом случае на первой итерации оно проверяет свойство '1'.) Мы хотим противоположность того, что возвращает (либо true или ложь) именно поэтому мы используем! в! uniq [obj.id]. Если uniq уже имеет свойство id, он возвращает значение true, которое оценивается как ложное (!), Говорящее функции фильтра НЕ добавлять этот объект. Однако, если он не находит свойство obj.id, он возвращает значение false, которое затем оценивается как true (!) И возвращает все справа от && или (uniq [obj.id] = true). Это истинное значение, указывающее методу фильтра добавить obj к возвращаемому массиву, а также добавляет свойство {1: true} в uniq. Это гарантирует, что любой другой экземпляр obj с тем же идентификатором не будет добавлен снова.
источник
источник
Я считаю, что сочетание
reduce
с,JSON.stringify
чтобы идеально сравнить объекты и выборочное добавление тех, кто еще не находится в аккумуляторе, является элегантным способом.Имейте в виду, что это
JSON.stringify
может стать проблемой производительности в крайних случаях, когда в массиве много объектов, и они являются сложными, но в большинстве случаев это самый короткий путь IMHO.Другой способ написать то же самое (но менее эффективно):
источник
Продолжаем исследовать способы удаления дубликатов из массива объектов в ES6: установка
thisArg
аргументаArray.prototype.filter
tonew Set
обеспечивает достойную альтернативу:Однако он не будет работать с функциями стрелок
() =>
, посколькуthis
связан с их лексической областью действия.источник
ES6 магия в одну строку ... читается при этом!
источник
Простое решение с помощью ES6 вспомогательных методов «уменьшить» и «найти» массива
Работает качественно и отлично отлично!
источник
Если вы не возражаете против сортировки вашего уникального массива впоследствии, это будет эффективным решением:
Таким образом, вам нужно только сравнить текущий элемент с предыдущим элементом в массиве. Сортировка один раз перед filtering (
O(n*log(n))
) дешевле, чем поиск дубликата во всем массиве для каждого элемента массива (O(n²)
).источник
Это простой способ, как убрать двуличие из массива объектов.
Я много работаю с данными, и это полезно для меня.
выведет на консоль:
источник
str это массив объектов. Существуют объекты, имеющие одинаковое значение (здесь небольшой пример, есть два объекта с одинаковым item_id, равным 2). check (id) - это функция, которая проверяет, существует ли какой-либо объект с таким же item_id или нет. если он существует, вернуть false, в противном случае вернуть true. В соответствии с этим результатом поместите объект в новый массив obj . Вывод приведенного выше кода
[{"item_id":1},{"item_id":2}]
источник
Вы слышали о библиотеке Лодаш? Я рекомендую вам эту утилиту, когда вы действительно не хотите применять свою логику к коду и использовать уже существующий код, который оптимизирован и надежен.
Подумайте о создании такого массива
Обратите внимание, что если вы хотите сохранить один атрибут уникальным, вы можете сделать это с помощью библиотеки lodash. Здесь вы можете использовать _.uniqBy
Этот метод похож на _.uniq (который возвращает версию массива без дубликатов, в которой сохраняется только первое вхождение каждого элемента), за исключением того, что он принимает iteratee, который вызывается для каждого элемента в массиве, чтобы сгенерировать критерий, по которому уникальность вычисляется.
Так, например, если вы хотите вернуть массив, имеющий уникальный атрибут 'place'
Точно так же, если вы хотите уникальный атрибут как «имя»
Надеюсь это поможет.
Ура!
источник