TL;DR: Список коротких и полезных JavaScript алгоритмов.
Отталкиваясь от моего опыта программирования на Ruby, во время изучения JavaScript, я был разочарован тем, что в языке упущены множество таких базовых методов как merge,flattenилиuniq.
Затем я открыл для себя lodash и это было круто… До тех пор, пока я не понял, что вам стоит быть очень осторожным во время обновлений, потому что очень легко сломать что-то самым невероятным способом (это конечно произошло и со мной; представьте себе, как это прекрасно отлаживать ваш код, когда lodash изменил используемый вами метод и теперь он делает почти тоже самое, но не совсем так как должен был это делать. И как бонус вы не сразу понимаете, что причина в lodash)
Несколько лет спустя, вещи кажутся мне проще благодаря новому стандарту ES6 и теперь я реже использую lodash или любую другую библиотеку для базовых алгоритмов. Вот не полный список того что я использую при написании кода.
Оговорка: Я не претендую на то чтобы превзойти lodash по эффективности или сложности. Кроме того, lodash это невероятный проект. Мои примеры это лишь несложные, простые в написании куски кода, которые работают быстро для достаточно простых случаев. Нам не всегда нужны тяжелые орудия.
Весь код ниже уважает принципы неизменности. Мы никогда не изменяем первоначальный объект, вместо этого мы будем возвращать новый объект с необходимыми свойствами.
Надеюсь это также поможет вам!
Уникальный массив
// get uniq from array
const numbers = [1, 2, 1, 1, 2, 1, 3, 4, 1 ]
const uniq = [...new Set(numbers)] // => [ 1, 2, 3, 4 ]
const uniq2 = Array.from(new Set(numbers)) // => [ 1, 2, 3, 4 ]
два способа унифицирование массива
Прежде чем переходить к массиву, помните, что у Set есть такие полезные методы как size или has.
Обновление объекта в массиве по свойству
Мы обновим объект с id: 3 в массиве.
// update an object in array by property
const initial = [ {id: 1, score: 1}, {id: 2, score: 2}, {id: 3, score: 4}]
const newValue = {id: 3, score: 3}
const updated = initial.map(x => x.id === newValue.id ? newValue : x)
console.log(updated) // => [ { id: 1, score: 1 }, { id: 2, score: 2 }, { id: 3, score: 3 } ]
Конечно “начальное” константа осталась нетронутой
Удаление объекта из массива по свойству
Давайте удалим объект из массива, для которого id === 3
// remove object from array by property
const removeId = 3
const without3 = initial.filter(x => x.id !== removeId)
console.log(without3) // => [ { id: 1, score: 1 }, { id: 2, score: 2 } ]
Начальный массив остался не тронутым
Удаления ключа из объекта
Мы можем использовать деструктуризацию в обратном направлении:
Объединение массива объектов
Следующим кодом мы можем с легкостью объединить вместе объекты или обновить их свойства:
// merge an array of objects
const data = [ {a: 1}, {b: 2}, {c: 3} ]
const merged = data.reduce((res, obj) => ({...res, ...obj}), {})
console.log(merged) // => { a: 1, b: 2, c: 3 }
// merge an array of objects by property
const toMerge = [
{ id: 1, value: 'a', },
{ id: 2, value: 'b', },
{ id: 3, value: 'c' },
{ id: 1, score: 1 },
{ id: 2, score: '2' },
]
const mergedByProperty = toMerge.reduce((result, obj) => ({
...result,
[obj.id]: {
...result[obj.id],
...obj
}
}), {})
console.log(mergedByProperty) // =>
/*
*{ '1': { id: 1, value: 'a', score: 1 },
* '2': { id: 2, value: 'b', score: '2' },
* '3': { id: 3, value: 'c' } }
*/
методы reduce и spread прекрасно работают вместе
Flatten
Преобразование многомерного массива в одномерный:
// flatten an array of arrays
const arrayOfArray = [ [1, 2], [3, 4], [[5, 6]] ]
const flattened = arrayOfArray.reduce((res, a) => [...res, ...a], [] )
console.log(flattened) // => [1, 2, 3, 4, [5, 6]]
преобразование первого уровня
FromPairs
Преобразование массива в объект из пар ключ-значение
// fromPairs
const pairs = [['a', 1], ['b', 2], ['c', 3]]
const asObjects = pairs
.reduce((res, [key, value]) => ({ ...res, [key]: value }), {})
// Or event smarter (thanks to @nomaed for pointing this one out)
const asObjects2 = { ...(new Map(pairs)) }
console.log(asObjects) // => { a: 1, b: 2, c: 3 }
мне очень нравится деструктурирующее присвоение
Вычитание из наборов
Удаление повторяющихся элементов из двух наборов (массивов)
// subtract two sets
const s1 = [ 1, 2, 3, 4, 5 ]
const s2 = [ 2, 4 ]
const subtracted = s1.filter(x => s2.indexOf(x) < 0)
console.log(subtracted)
не так часто используемое, но вся равно полезное
Заключение
Вот и все на сегодня. Не стесняйтесь отправить мне больше примеров или попросите меня показать алгоритм, который я забыл! Я бы с радостью обновил этот список :)