Несколько способов устранения дублей в 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
) будет уникально.