How to remove duplicates from an array? Three ways. (JavaScript)
Вставка
- Опубліковано 17 лют 2019
- В этом видео вы узнаете 3 способа удаления дубликатов из массива в JS - как сделать так, чтобы остались только уникальные элементы.
--
Решение с reduce: codepen.io/puzankov/pen/zeMrbN
Документация:
- Set: developer.mozilla.org/en-US/d...
- Array includes: developer.mozilla.org/en-US/d...
- Array indexOf: developer.mozilla.org/en-US/d...
- Array filter: developer.mozilla.org/en-US/d...
- Array reduce: developer.mozilla.org/en-US/d...
--
Задавайте ваши вопросы в комментариях. А также пишите, на какие темы вам хотелось бы увидеть новые выпуски.
Если видео было для вас полезным, ставьте лайк и поделитесь им с друзьями.
---
Подписывайтесь на наш канал: bit.ly/fs-ytb
---
Присоединяйтесь к нам в соцсетях:
FB: / frontendscience
Telegram: t.me/frontend_science
Instagram Сергея Пузанкова: / puzankovcom
Заходите на наш сайт: frontend-science.com/
Очень много спасибо!!!! Я учусь на Ваших видео . Пожалуйста не останавливайся. Всё у вас просто и понятно. Мне нужно срочно выучить мой любимый JavaScript!!!
Спасибо за такие прекрасные обучающие видео, все просто и понятно, без лишней воды!
Шикарное объяснение! Спасибо! И отдельное спасибо за рассмотрение разных способов.
Спасибо за поддержку! рады стараться :)
@@frontendscience привет, у меня вопрос а как можно фильтровать элементы на уникальность при пуше? Пример, у меня есть форма подписки на емаил рассылку при отправлении формы я проверяю есть ли данный емаил в массиве и если есть возвращая ошибку мол эта почта уже подписана на рассылку, вчера сидел часа три ничего в голову не прошло, дали опыта мало в js по-хорошему это все на бэкенде надо хранить в базе данных так как при обновлении страницы все это слетит, но для начала хотя бы такую проверку сделать бы, спасибо заранее)
@@awenn2015 Если нужно проверить пачку email'ов существуют ли они уже в системе я бы использовал один из двух вариантов: либо создать объект в котором ключами будут email'ы, либо сделать new Set() и после этого можно очень быстро проверять есть ли такой email уже или нет. Если нету то добавлять.
Реализация - Пушка!! Один способ краше другого!🚀🌠
Благодарность !
Очень круто спасибо.❤
Спасибо большое за ваш труд!)
Спасибо, Мария, за поддержку! Рады, что Вам нравится наш контент)
Спасибо большое.
привет! для п. 2 есть небольшое дополнение: фильтр, как и многие методы массива, принимает 3 параметром (редюс 4) сам исходный массив. в ретурн можно его прописать, потому что если я захочу поменять название своего массива, это придется делать 3 местах: инициализация, фильтр и тело функции фильтрации
для п.3 можно сделать больше строчек кода, но меньшую сложность алгоритма через обычный объект и фильтр / Object.keys
Если в варианте с reduce() использовать push() для добавления нового элемента, то в последующих итерации метод includes() работать не будет так как колбэком будет число
Ничего себе...
Interface Set
Since: 1.2
December 1998
Вау...Продолжайте парни )))
Довольно нативное решение для JS через уникальность ключей в объекте
const array = ['a','b','c','a','b'];
let temp = {};
array.forEach((item, i) => temp[item] = i);
Object.keys(temp);
Да это тоже клевое решение. Я раньше часто использовал такой подход.
Почему объект по итогу {a: 3, b: 4, c: 2}, а не {a: 0, b: 1, c:2 }
А, все - он переписал в цикле, хитро
@@kawaikaino5277 Потому что когда итератор дойдет до второй "а" у которой индекс 3, он перетрет значение свойства "а" в объекте (которое уже будет выставлено в 0). Но самое главное - все равно что записано будет в качестве значения в объекте. Для решения этой задачи важны только сами ключи в объекте. Благодаря Object.keys(temp); - все имена ключей превратятся в новый массив уникальных.
Good )
А вообще почему использовать массывы? В чем объект {} проблемы?
Спасибо за подробное объяснение!) А есть "нерегистрочувствительный" способ для элементов массива?) Иными словами: есть исходный массив ["asd", "ASD", "Asd", "bcd"], но на выходе должны получить только ["asd", "bcd"]
Заранее спасибо)
Ну так как на выходе по умолчанию мы получаем все только в нижнем регистре то тут все просто выйдет:
const uniqArray = array.reduce((uniq, item) => {
item = item.toLoverCase(); //Добавляем приведение к нижнему регистру и все.
return uniq.includes(item) ? uniq : [...uniq, item];
}, [])
@@frontendscience Спасибо большое!)
А сложность какая и затраты?
а если есть массив объектов, где нужно получить массив уникальных объектов
А не можете помочь розобраться как изменить объект в массиве??
Т.е. есть функция с объектом которая принимает значение трёх inputov..
const arr= []
function render{
Obj = {
id = Math.floor(Math.random() * 50) +1,
name : input.value,
last name : input2.value,
email: input3.value,
}
arr.push(obj);
}
Эти все данные кидаются в таблицу...потом есть кнопка edit(которая кидает назад в inputы) и я например слегка изменяю данные имени там email ...и хочу их вернуть в изменённом виде назад..НО незнаю как это сделать
Мне тут подсказывали что как-то по id объект...но я учусь и что-то запутался(((
важный момент - Math.floor(Math.random() * 50) +1, вот этот код должен быть вне объекта. В объект должны записываться конечные данные - например id: 12345. Далее когда функция рендерит в таблице эти данные на кнопку edit надо повесить аттрибут data-id=12345. в обработчике edit тогда обращаться к obj['12345'].email и менять email к примеру
@@frontendscience спасибо
круто! дякую за відео. А як можна через push у тренарному виразі написати? мені чомусь undefined вертає(
Тернарный оператор предназначен для присвоения значения. Можно вначале сделать значение котрое хотим запушить. let someVal = (codition)? 'var1' : 'var2'; arrat.push(someVal); Вот так можно использовать с push
Через push, с использование тернарного оператора можно сделать следующим образом:
arr.reduce((resArr, item) => resArr.includes(item) ? resArr : (resArr.push(item), resArr), [])
1. resArr.includes(item) - проверяет есть ли элемент в результатирующем массиве resArr
2. resArr - если есть, то возвращает (return) исходный массив
3. (resArr.push(item), resArr) - если нет, то
а. сначала мы push'им в результирующий массив элемент item
b. затем возвращаем (return) его.
Оператор "запятая" обрабатывает последовательно команды и возвращает только последнюю. Чтобы это было в одном выражении оборачиваем скобками.
Если бы мы просто написали после двоеточия - resArr.push(item), то, согласно документации нам бы вернулось числовое значение равное длине новообразованного массива, а нам нужно возвращать массив, поэтому с push'ем именно таким образом сделано.
Почему-то первый способ не работает у меня, хотя вроде все также ввожу...
Никита, может быть несколько причин. 1) банальная опечатка. От этого может спасти эта ссылка: codepen.io/puzankov/pen/zeMrbN тут работающий код. 2) старый браузер, который не поддерживает ES6 arrow functions. в любом случае надо открывать консоль и смотреть что именно пошло не так.
який метод працює швидше? Дякую
тут многое зависит от данных и их размера. Но из современных вроде как Array.from(new Set()) показывает отличные результаты.
7:44, Spread тут плохой вариант, так как работает намного медленнее push()
Да как я и сказал - push тоже можно использовать. Просто с ним код вышел бы не таким лаконичным. В плане производительности этот вариант (последний) в принципе самый медленный - поэтому его можно использовать на маленьких массивах. А в этом случае разницы между push или spread не будет заметен.
@@frontendscience Да, так-то spread выглядит красивее в коде, но если массив большой, то разница в скорости колоссальная.
@@alekssjeva951 Да, это так. При использовании любого алгоритма надо понимать в каких условиях он будет использоваться. Какие входные данные и их объем.
@@alekssjeva951 Привет, где можно почитать про скорости выполнения тех или иных операций!. Заранее спс
Очень ждал, что в конце будет приведена сложность каждого из алгоритмов. Не дождался(((
А должно было быть?
@@frontendscience Ну мне кажется это логичным, что если приводится три алгоритма решения задачи, то в конце рассмотреть сложность каждого алгоритма и целесообразность его использования. Ради интереса замерил время выполнения для каждого варианта. Так, при использовании массива в 10 миллионов элементов время выполнения 1-го алгоритма в среднем 180мс, 2-го - 210мс и 3-го - 235мс. Т.е. разница небольшая и сложность каждого будет O(n*n). По сути можно спокойно пользоваться каждым из них, но 1-й лучше т.к. быстрее работает и быстрее пишется))) Но самым быстрым оказался вариант с использованием объекта - 145мс.
Уважаемый Дмитрий, я рассказал ровно столько, сколько посчитал нужным в данном видео. И поделился рабочими крутыми вариантами. Если Вам нужно учитывать сложность каждого из этих вариантов в Вашем конкретном примере (потому что конкретно Ваш пример с большими объемами данных) - то Вы берете и замеряете эту сложность и выбираете какой из предложенных мной способов конкретно в Вашем случае Вам больше подходит. А не рассказываете мне, как Вы разочарованы, что я не указал сложность алгоритмов. Сложность алгоритмов не равно время отработки Вашего кода. Почитайте подробнее про это.
@@frontendscience Жаль. Так хотелось Вам рассказать...
@@user-nyxxx это на другие каналы.
Конвертировать массив в множество
import { uniq } from 'lodash'
uniq(someArray);
ждал упоминание этого способа в видео