Как вернуть новый массив объектов только с уникальным id вложенного объекта?

https://codesandbox.io/s/relaxed-resonance-3r2cf?f...

Вот из такого массива нужно вернуть новый массив без дублей по user.id

const arr = [
  {
    message: "фыа",
    user: {
      id: 0
    }
  },
  {
    message: "dhfas",
    user: {
      id: 2
    }
  },
  {
    message: "asidfaks",
    user: {
      id: 2
    }
  },
  {
    message: "ouosbop",
    user: {
      id: 3
    }
  },
  {
    message: "nvcbksad",
    user: {
      id: 0
    }
  }
];
  • Вопрос задан
  • 291 просмотр
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
Сделаем функцию, которая будет принимать следующие параметры:
  • массив, подлежащий уникализации
  • функцию, принимающую элемент массива и возвращающую значение, по которому осуществляется уникализация

Чтобы можно было делать так: const result = unique(arr, n => n.user.id);.

Какие тут возможны варианты:

const unique = (arr, key) =>
  Object.values(Object.fromEntries(arr.map(n => [ key(n), n ])));

// или, если в результирующий массив должны попадать те из "одинаковых" элементов,
// что расположены в исходном массиве первыми

const unique = (arr, key) =>
  Object.values(arr.reduce((acc, n) => (acc[key(n)] ??= n, acc), {}));

// или, если надо также сохранять взаимное расположение элементов

const unique = (arr, key) =>
  arr.filter(function(n) {
    const k = key(n);
    return !(this[k] = this.hasOwnProperty(k));
  }, {});

Если значения, по которым осуществляется уникализация, могут, будучи различными, иметь одинаковый строковый эквивалент, то на помощь приходят Map и Set:

const unique = (arr, key) =>
  Array.from(new Map(arr.map(n => [ key(n), n ])), n => n[1]);

// или (в отличие от объекта, Map запоминает порядок вставки,
//      так что тут взаимное расположение элементов сохраняется)

const unique = (arr, key) =>
  [...arr.reduce((acc, n) => {
    const k = key(n);
    return acc.set(k, acc.get(k) ?? n);
  }, new Map).values()];

// или

const unique = (arr, key) =>
  arr.filter(function(n) {
    const k = key(n);
    return !this.has(k) && this.add(k);
  }, new Set);
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы