Как убрать из массива повторяющиеся элементы js
Перейти к содержимому

Как убрать из массива повторяющиеся элементы js

  • автор:

3 способа удаления дубликатов из массива в JS

3 способа удаления дубликатов из массива в JS

Существует три способа удаления дубликатов из массива. В данной статье рассмотрим каждый из них и выясним наиболее подходящий.

Первый способ удаления дубликатов из массива.

Перед нами массив arr, где дублируются некоторые числа. Наша задача создать новый массив или преобразовать текущий массив, но без дубликатов. Для решения задачи, воспользуемся объектом set. Объект set может содержать в себе только уникальные элементы.

// Массив arr
const arr = [1, 2, 3, 5, 1, 6, 2, 5, 6, 7];
console.log(arr);

3 способа удаления дубликатов из массива в JS.

Создадим новую переменную arr_1 и применим объект set к исходному массиву. Метод new Set создает новую коллекцию. В результате мы получили новый набор (коллекцию) с уникальными числами, а все дубли исчезли.

let arr_1 = new Set(arr);
console.log(arr_1);

3 способа удаления дубликатов из массива в JS.

Элементы набора заключены в фигурные скобки, а массива — в квадратные. Как же нам получить все-же массив? Это можно сделать двумя способами: через оператор расширения spreаd (. ) или через метод Array.from().

// Spread
let arr_1 = [. new Set(arr)];
console.log(arr_1);

или аналогичный вариант

// Array.from
let arr_1 = Array.from(new Set(arr));
console.log(arr_1);

Оператор spread и метод Array.from() проделали одну и туже работу — преобразовали коллекцию в массив.

3 способа удаления дубликатов из массива в JS.

Второй способ удаления дублей

Метод filter() создает новый массив. Он вызывает callback функцию для каждого элемента массива. Элементы массива не прошедшие проверку, вылетают из вновь созданного массива. Метод filter() передает в callback функцию два параметра исходного массива: элемент массива и его индекс (порядковый номер в массиве). Метод indexOf сверяет индексы, начиная с первого, в исходном и в новом массиве. Если позиция текущего элемента совпадает с найденной, значит этот элемент уникальный и он добавляется в новый массив. Но, если индексы у одного и того же элементы не совпадают, значит это дубликат и он уже не попадет в новый массив.

// Filter
let arr_2 = arr.filter((item, index) => <
return arr.indexOf(item) === index
>);
console.log(arr_2);

Массив дублей

Если перед знаками равно поставить восклицательный знак, то мы получим противоположный эффект. В новом массиве останутся только дубли.

let arr_2 = arr.filter((item, index) => <
return arr.indexOf(item) !== index
>);
console.log(arr_2);

3 способа удаления дубликатов из массива в JS.

Третий способ удаления дублей

Метод reduce() тоже метод перебора массива и он принимает callback функцию с двумя параметрами: result и item. В переменной result будет накапливаться результат, а item является текущим элементом. Метод includes проверяет, есть ли текущий элемент в переменной result. Если есть, то возвращается result и ничего не происходит. В противном случае, мы добавляем в result текущий элемент и все это преобразуем обратно в массив.

// Reduce
let arr_3 = arr.reduce((result, item) => <
return result.includes(item) ? result : [. result, item];
>, []);
console.log(arr_3);

Первый способ по удалению дубликатов из массива оказался самым простым и коротким. Второй способ я люблю за дополнительную возможность сформировать массив из дубликатов. Ну, а третий способ слишком замороченный и приходится писать больше кода. Поэтому, я выбираю первый способ.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Она выглядит вот так:

Комментарии ( 0 ):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.

Как убрать дублирующиеся значения из массива в Javascript

Как убрать дублирующиеся значения из массива в Javascript

В этой статье затронем один из самых популярных поисковых запросов среди junior-разработчиков: «Как убрать дублирующиеся значения из массива в Javascript». Я расскажу про самые популярные способы и распишу их плюсы и минусы. Конечно же, в каждом из предложенных решений, код можно будет сократить и упростить, но я оставлю его как есть в образовательных целях.

Представим, что у нас есть массив вида:

Теперь попробуем удалить из него дубликаты.

Используем Set

Set — это новый тип данных, представленный в ES6. Значения Set могут присутствовать только в одном экземпляре, тем самым этот тип данных подразумевает наличие только уникальных элементов. Соответственно, если мы передадим Array в Set, то мы получим объект только с уникальными значениями.

Перейдем к коду:

  1. Первое, что необходимо сделать — это передать массив в сет.
  2. Второе — используя spread оператор, преобразовать сет обратно в массив. Так же spread можно заменить на Array.from(uniqSet) .

Теперь давайте максимально укоротим код для того, чтобы оценить количество строк.

Плюсы:

  • Производительность. Этот вариант самый производительный. Согласно нотации Big O, сложность алгоритма будет равна O(2n), что в действительности является O(n), а значит производительность максимальная.
  • Краткость. Самая короткая запись из всех возможных вариантов.

Минусы:

  • Обработка только примитивных типов данных. Данный способ не работает, если в массиве будут присутствовать объекты.

Используем filter

Второй вариант удаления — это использование методов массивов .filter() и .indexOf() . Рассмотрим, что делает каждый из них.

Что такое indexOf

Метод .indexOf() возвращает индекс первого, найденного элемента из массива.

Что такое filter

Метод .filter() создаёт новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции. Другими словами, если элемент проходит условие и возвращает true, тогда он будет включен в новый массив, непрошедшие элементы будут пропущены.

Решение, используя filter

После того, как вы узнали о .filter() и .indexOf() , перейдем к коду:

Все что необходимо сделать, это перебрать каждое значение массива и сравнить, равен ли индекс первого значения, текущему, если да, то добавляем значение в новый массив.

Если мы заглянем внутрь arr.filter((el, id) => arr.indexOf(el) === id); , то там происходит примерно это:

Элемент Индекс элемента indexOf Соответствие условию indexOf(el) === id
1 0 0 true
2 1 1 true
3 2 2 true
1 3 0 false
1 4 0 false
‘1’ 5 5 true

И так далее с каждым элементом.

Плюсы:

  • Популярность. Метод фильтр знаком огромному количеству разработчиков, соответственно, написать решение используя .filter() очень просто.
  • Возможность расширить логику для того, чтобы проверять уникальность объектов и массивов. В данном случае мы можем включить в условие более сложную логику, которая будет проверять на уникальность вложенные массивы и объекты.

Минусы:

  • Производительность. В данном случае у нас используется цикл в цикле, т.е. первый цикл это .filter() , а второй .indexOf() , соответственно сложность алгоритма O(n^2), это значительно медленнее, чем первый вариант. Если вам необходимо очистить массив с большим количеством элементов, то я не рекомендую использовать данный подход.

Используем reduce

На самом деле, использование .reduce() не принесет вам никакой выгоды, по сравнению с .filter() , просто немного другая логика.

В итоге, мы имеем такие же проблемы с производительностью, т.к. используется цикл в цикле — .reduce() и .indexOf() соответственно. В дополнение к этому, не все разработчики могут быть знакомы с .reduce() . Не самый лучший способ для решения задачи.

Используем цикл for

В случае, если вам необходима производительность, то лучшим решением, по сравнению с .filter() и .reduce() будет обычный цикл for .

  • Во-первых, сам for быстрее, чем все ES6 методы массивов.
  • Во-вторых, вы можете написать O(n) решение, вместо O(n^2).
  • В-третьих, расширить логику на проверку уникальности вложенных массивов и объектов будет так же просто, как в .filter() и .reduce() .

Давайте теперь разберемся, что здесь вообще происходит.

  1. Обозначаем hashtable const seen = <> , в который будем записывать все значения массива, что мы встретили.
  2. Обозначаем массив, в который будем записывать только уникальные значения. const result = [] .
  3. Обозначем переменную let j = 0 , которая будет использована для быстрой записи значений в массив result .
  4. Запускаем цикл for для полученного массива.
  5. Для уменьшения количества обращений к массиву, создаем константу const item = arr[i] .
  6. При записи элемента в hashtable в качестве ключа, он будет преобразован в строку, поэтому узнаем его тип и создаем ключ вида type_value
  7. Проверяем наличие значения в hashtable, если значения нет, то проваливаемся внутрь условия.
  8. Так как в hashtable не нашлось искомое значение, то записываем его.
  9. Опять же, так как в hastable не нашлось искомое значение, значит его можно считать уникальным и нужно поместить в массив результатов. Для этого можно воспользоваться методом array.push() , но его сложность будет O(n), а присвоить значение напрямую через индекс — O(1), поэтому испольуем индекс.

Плюсы

  • Производительность. Согласно Big O нотации, сложность алгоритма будет O(n), производительность максимальная.
  • Возможность расширить логику для того, чтобы проверять уникальность объектов и массивов.

Минусы

  • Количество кода. По сравнению с любым из предложенных способов, данный имеет самую длинную запись.
  • Императивный способ. Еще один минус в читаемости данного подхода, декларативный читается лучше.

Заключение

В этой статье я рассмотрел несколько способов для удаления дублирующихся значений из массивов. Есть еще варианты, например, написать через .forEach() или через прототип массива, но в целом, они мало отличаются от предложенных. Главным критерием в выборе подхода, для вас должен стать набор входных данных, если вы имеете дело с огромным количеством значений, то лучше позаботиться о производительности, в остальных случаях я бы предпочел более короткую и читаемую запись.

How to remove all duplicates from an array of objects?

I’m wondering what is the best method to remove duplicate objects from an array. So for example, obj.arr would become.

chickens's user avatar

77 Answers 77

How about with some ES6 magic?

A more generic solution would be:

Using the above property strategy instead of JSON.stringify :

You can add a wrapper if you want the propNames property to be either an array or a value:

allowing both getUniqueItemsByProperties(‘a’) and getUniqueItemsByProperties([‘a’]);

Explanation

    Start by understanding the two methods used:

      , findIndex

    VLAZ's user avatar

    Eydrian's user avatar

    One liners with filter ( Preserves order )

    Find unique id ‘s in an array.

    If the order is not important, map solutions will be faster: Solution with map

    Unique by multiple properties ( place and name )

    Unique by all properties (This will be slow for large arrays)

    Keep the last occurrence by replacing findIndex with findLastIndex .

    chickens's user avatar

    Using ES6+ in a single line you can get a unique list of objects by key:

    It can be put into a function:

    Here is a working example:

    How does it work

    First the array is remapped in a way that it can be used as an input for a Map.

    which means each item of the array will be transformed in another array with 2 elements; the selected key as first element and the entire initial item as second element, this is called an entry (ex. array entries, map entries). And here is the official doc with an example showing how to add array entries in Map constructor.

    Example when key is place:

    Secondly, we pass this modified array to the Map constructor and here is the magic happening. Map will eliminate the duplicate keys values, keeping only last inserted value of the same key. Note: Map keeps the order of insertion. (check difference between Map and object)

    new Map(entry array just mapped above)

    Third we use the map values to retrieve the original items, but this time without duplicates.

    And last one is to add those values into a fresh new array so that it can look as the initial structure and return that:

    V. Sambor's user avatar

    Simple and performant solution with a better runtime than the 70+ answers that already exist:

    Example:

    How it works:

    Array.filter() removes all duplicate objects by checking if the previously mapped id-array includes the current id ( destructs the object into only its id). To only filter out actual duplicates, it is using Array.includes() ‘s second parameter fromIndex with index + 1 which will ignore the current object and all previous.

    Since every iteration of the filter callback method will only search the array beginning at the current index + 1, this also dramatically reduces the runtime because only objects not previously filtered get checked.

    This obviously also works for any other key that is not called id , multiple or even all keys.

    leonheess's user avatar

    A primitive method would be:

    Bricky's user avatar

    aefxx's user avatar

    If you can use Javascript libraries such as underscore or lodash, I recommend having a look at _.uniq function in their libraries. From lodash :

    Basically, you pass in the array that in here is an object literal and you pass in the attribute that you want to remove duplicates with in the original data array, like this:

    UPDATE: Lodash now has introduced a .uniqBy as well.

    ambodi's user avatar

    I had this exact same requirement, to remove duplicate objects in a array, based on duplicates on a single field. I found the code here: Javascript: Remove Duplicates from Array of Objects

    So in my example, I’m removing any object from the array that has a duplicate licenseNum string value.

    James Drinkard's user avatar

    One liner using Set

    1. new Set(myData.map(JSON.stringify)) creates a Set object using the stringified myData elements.
    2. Set object will ensure that every element is unique.
    3. Then I create an array based on the elements of the created set using Array.from.
    4. Finally, I use JSON.parse to convert stringified element back to an object.

    ES6 one liner is here

    sravan ganji's user avatar

    To remove all duplicates from an array of objects, the simplest way is use filter :

    аlex's user avatar

    One liners with Map ( High performance, Does not preserve order )

    Find unique id ‘s in array arr .

    If the order is important check out the solution with filter: Solution with filter

    Unique by multiple properties ( place and name ) in array arr

    Unique by all properties in array arr

    Keep the first occurrence in array arr

    chickens's user avatar

    Here’s another option to do it using Array iterating methods if you need comparison only by one field of an object:

    Alex Kobylinski's user avatar

    This is a generic way of doing this: you pass in a function that tests whether two elements of an array are considered equal. In this case, it compares the values of the name and place properties of the two objects being compared.

    ES5 answer

    Original ES3 answer

    DevDavid's user avatar

    If you can wait to eliminate the duplicates until after all the additions, the typical approach is to first sort the array and then eliminate duplicates. The sorting avoids the N * N approach of scanning the array for each element as you walk through them.

    The «eliminate duplicates» function is usually called unique or uniq. Some existing implementations may combine the two steps, e.g., prototype’s uniq

    This post has few ideas to try (and some to avoid 🙂 ) if your library doesn’t already have one! Personally I find this one the most straight forward:

    I think the best approach is using reduce and Map object. This is a single line solution.

    doğukan's user avatar

    To add one more to the list. Using ES6 and Array.reduce with Array.find .
    In this example filtering objects based on a guid property.

    Extending this one to allow selection of a property and compress it into a one liner:

    To use it pass an array of objects and the name of the key you wish to de-dupe on as a string value:

    leonheess's user avatar

    You could also use a Map :

    Pragmateek's user avatar

    Dang, kids, let’s crush this thing down, why don’t we?

    Cliff Hall's user avatar

    One-liner using ES6 and new Map() .

    1. Doing .map() on the data list and converting each individual object into a [key, value] pair array(length =2), the first element(key) would be the stringified version of the object and second(value) would be an object itself.
    2. Adding above created array list to new Map() would have the key as stringified object and any same key addition would result in overriding the already existing key.
    3. Using .values() would give MapIterator with all values in a Map ( obj in our case)
    4. Finally, spread . operator to give new Array with values from the above step.

    Savan Akbari's user avatar

    A TypeScript solution

    This will remove duplicate objects and also preserve the types of the objects.

    Solution Via Set Object | According to the data type

    Set Object Feature

    Each value in the Set Object has to be unique, the value equality will be checked

    The Purpose of Set object storing unique values according to the Data type , whether primitive values or object references.it has very useful four Instance methods add , clear , has & delete .

    Unique & data Type feature.

    add method

    it’s push unique data into collection by default also preserve data type .. that means it prevent to push duplicate item into collection also it will check data type by default.

    has method

    sometime needs to check data item exist into the collection and . it’s handy method for the collection to cheek unique id or item and data type..

    delete method

    it will remove specific item from the collection by identifying data type..

    clear method

    it will remove all collection items from one specific variable and set as empty object

    Set object has also Iteration methods & more feature..

    removeDuplicates() takes in an array of objects and returns a new array without any duplicate objects (based on the id property).

    First, we set the value of variable uniq to an empty object.

    Next, we filter through the array of objects. Filter creates a new array with all elements that pass the test implemented by the provided function.

    Above, we use the short-circuiting functionality of &&. If the left side of the && evaluates to true, then it returns the value on the right of the &&. If the left side is false, it returns what is on the left side of the &&.

    Удалить дубликаты из массива в JavaScript

    В этом посте мы обсудим, как удалить повторяющиеся значения из массива в JavaScript.

    1. Использование Array.prototype.filter() функция

    Простое решение — проверить второе вхождение для каждого элемента массива. Это можно легко сделать с помощью indexOf() метод с filter() метод следующим образом:

    2. Использование набора

    Приведенное выше решение не рекомендуется из-за серьезных проблем с производительностью для больших массивов. Эффективным решением является преобразование массива в Set структуру данных, а затем преобразовать набор обратно в массив. Это решение работает как Set хранить уникальные значения и устраняет повторяющиеся значения. Обратите внимание, что это решение может изменить исходный порядок элементов, присутствующих в массиве.

    Это может быть реализовано с помощью Set конструктор и Array.from() метод.

    В качестве альтернативы вы можете использовать оператор Spread (. ) чтобы преобразовать набор обратно в массив.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *