Способы устранения дублей в JavaScript-массивах

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

See this code Resolve duplication in array with Set on x.xhtml.ru.

Однако, теперь массивы превратились в объекты 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 превращается обратно в массив.

See this code Resolve duplication in array with custom function on x.xhtml.ru.

Удаление дублей с помощью только методов массива

Если не хочется выполнять лишние преобразования в 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) будет уникально.

See this code Resolve duplication in array with custom function 2 on x.xhtml.ru.