Несколько способов устранения дублей в JavaScript-массивах без использования циклов, с помощью объекта Set или методов массива: filter(), reduce() и пр.
Массив с повторяющимися строками или числами
const dupStrings = ['Angular', 'React', 'VueJS', 'Svelte', 'React']
const dupNumbers = [1, 2, 3, 4, 5, 6, 2, 4, 6, 7, 8, 9, 0],
const dupMixed = [1, 2, 3, 4, 5, 6, 2, 4, 6, 7, 8, 9, 0,
"1", "2", "3", "4", "5", "6", "2", "4", "6", "7", "8", "9", "0"];
В первом массиве повторяются только строки, во втором будут только повторяющиеся числа, в третьем – смесь из чисел и строк.
Чтобы избавиться от повторяющихся данных, можно воспользоваться объектом Set. Set принимает только уникальные значения. При этом, учитывается тип значения, т.е. число 1 и 1 в строке будут различаться.
“Объекты
Setпредставляют коллекции значений, по которым вы можете выполнить обход в порядке вставки элементов. Значение элемента вSetможет присутствовать только в одном экземпляре, что обеспечивает его уникальность в коллекцииSet” – MDN Web Docs.
console.log(new Set(dupStrings))
// Set(5) {"Angular", "React", "VueJS", "Svelte", ""}
console.log(new Set(dupNumbers))
// Set(10) {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
console.log(new Set(dupMixed))
// Set(20) {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
Если поместить массивы с дублями в объект Set и вывести его содержимое в консоль, будет видно, что повторяющиеся значения удалены и в Set остались только уникальные значения строк и чисел.
Однако, теперь массивы превратились в объекты Set, а это не одно и то же. Поэтому нужно преобразовать каждый Set обратно в массив.
Один из простых способов сделать это – использовать синтаксис ...spread внутри квадратных скобок [...].
Для многократного использования всех преобразований, лучше разместить их в функции:
function unDuplicateArraySingleValues(array) {
// Проверка, что это не пустой массив
if ((Array.isArray(array) || array instanceof Array)
&& array.length) {
// Возвращает массив уникальных значений
return [...new Set(array)];
// или return Array.from(new Set(array));
} else {
// Это не заполненный массив,
// возвращаем переданное без изменений
return array;
}
}
Что делает функция unDuplicateArraySingleValues
В функцию передаётся параметр array, в котором ожидается не пустой массив. В операторе if проверяется, что передан массив и в нём есть элементы.
Если условия выполняются, массив вызовом new Set() преобразуется в объект Set. Затем с помощью ...spread синтаксиса Set превращается обратно в массив.
Удаление дублей с помощью только методов массива
Если не хочется выполнять лишние преобразования в Set и обратно, можно использовать только методы массивов, например с помощью array.reduce():
function unDuplicateArraySingleValues(array) {
// Проверка, что это не пустой массив
if ((Array.isArray(array) || array instanceof Array)
&& array.length) {
// Возвращает массив уникальных значений
return array.reduce((resArr, currValue) => {
return resArr.includes(currValue) ? resArr : [...resArr, currValue];
}, []);
} else {
// Это не заполненный массив,
// возвращаем переданное без изменений
return array;
}
}
Или так, с помощью array.filter():
function unDuplicateArraySingleValues(array) {
// Проверка, что это не пустой массив
if ((Array.isArray(array) || array instanceof Array)
&& array.length) {
// Возвращает массив уникальных значений
return array.filter((currValue, ind) => {
return array.indexOf(currValue) === ind;
});
} else {
// Это не заполненный массив,
// возвращаем переданное без изменений
return array;
}
}
Этот вариант хорош ещё тем, что если его немного переделать, то легко можно получить наоборот массив из дублей значений исходного, так:
return array.filter((currValue, ind) => {
// вернёт массив из дублей
return array.indexOf(currValue) !== ind;
});
Массив из повторяющихся объектов
Здесь пример более сложного массива с дублями объектов.
const dupObjects = [
{ id: 1, name: "a", value: "c" },
{ id: 2, name: "b", value: "d" },
{ id: 2, name: "c", value: "e" },
{ id: 3, name: "d", value: "c" }
];
Значения нескольких свойств (id=2 и value="c") дублируются.
Понадобится ещё одна функция, которая проверит такой массив. Используя переданное вторым аргументом название свойства (например "id"), она определит, есть ли в массиве объект с таким же значением в таком же свойстве.
function unDuplicateArrayObjects(array, propertyName) {
if ((Array.isArray(array) || array instanceof Array)
&& array.length
&& typeof propertyName === 'string'
&& propertyName.length) {
// Массив значений из ключа propertyName, который надо проверить
const objectValuesArrayFromKey = array.map(item => item[propertyName]);
// Удалить дубли этих значений с помощью предыдущей функции
const uniqueValues = unDuplicateArraySingleValues(objectValuesArrayFromKey);
// Вернуть массив только с уникальными объектами
return uniqueValues.map(
key => array.find(
item => item[propertyName] === key
)
);
} else {
return array;
}
}
Что делает функция unDuplicateArrayObjects
Эта функция подойдёт для массива из объектов с одинаковыми названиями свойств. После преобразования в новом массиве должны остаться только объекты, у которых значение одного из свойств (в примере – id) будет уникальным.
Теперь в функцию передаются 2 аргумента: array – исходный массив с объектами и propertyName – свойство в этих объектах, у которого должны быть уникальные значения.
В операторе if проверяется, что в array передан массив и в нём есть элементы, а также propertyName для которого ожидается не пустая строка.
В константу-массив objectValuesArrayFromKey сохраним значения свойства всех объектов из исходного массива, название которого передано в параметре propertyName.
В uniqueValues теперь нужно удалить повторяющиеся значения. Для этого подойдёт предыдущая функция unDuplicateArraySingleValues(array), которая вернёт новый массив с уникальными значениями.
В конце, с помощью массива uniqueValues возвращается массив только с объектами, у которых значение запрашиваемого свойства (в примере – id) будет уникально.

