Как удалить из массива повторяющиеся имена?

Например, есть массив объектов:

var array = [
    {name:"Joe", date:'2018-07-08' },
    {name:"Mars", date:'2018-07-20'},
    {name:"Joe", date:'2018-07-02'},
    {name:"Saturn", date:'2018-07-01'},
    {name:"Joe", date:'2018-07-02'},
    {name:"Mars", date:'2018-07-01'},
]

На выходе - оставить только имя с последней датой добавления:

var array = [
    {name:"Joe", date:'2018-07-08' },
    {name:"Mars", date:'2018-07-20'},
    {name:"Saturn", date:'2018-07-01'},
]

Удалились {name:"Joe", date:'2018-07-02'}, {name:"Joe", date:'2018-07-08'}, {name:"Mars", date:'2018-07-01'}

В итоге остались уникальные имена и с последней датой добавления.


Ответы (3 шт):

Автор решения: entithat

Сортируем по дате. Потом проходимся по каждому элементу и проверяем есть ли он в массиве уже.

const arr = [
    {name:"Joe", date:'2018-07-08' },
    {name:"Joe", date:'2018-07-02'},
    {name:"Joe", date:'2018-07-02'},
    {name:"Saturn", date:'2018-07-01'},
    {name:"Mars", date:'2018-07-01'},
    {name:"Mars", date:'2018-07-20'},
];

console.log(
  arr
    .sort((a, b) => new Date(b.date) - new Date(a.date))
    .reduce((a, c) => {
      if (Object.values(a).map(e=>e.name).indexOf(c.name) === -1) a.push(c);
      return a;
    }, [])
);

→ Ссылка
Автор решения: Aziz Umarov

Думаю сортировка лишняя если как в желаемом ответе.

var array = [
    {name:"Joe", date:'2018-07-08' },
    {name:"Mars", date:'2018-07-20'},
    {name:"Joe", date:'2018-07-02'},
    {name:"Saturn", date:'2018-07-01'},
    {name:"Joe", date:'2018-07-02'},
    {name:"Mars", date:'2018-07-01'},
]

let result = [...array]
    .reduce((a, c) => (a.map(e=>e.name).includes(c.name) || a.push(c), a), []);

console.log(result);

А если просить тотже ответ но с последней датой обновления

var array = [
    {name:"Joe", date:'2018-07-08' },
    {name:"Mars", date:'2018-07-20'},
    {name:"Joe", date:'2018-07-02'},
    {name:"Saturn", date:'2018-07-01'},
    {name:"Joe", date:'2018-07-02'},
    {name:"Mars", date:'2018-07-01'},
]

let result = array.filter(item => [...array]
    .sort((a, b) => new Date(b.date) - new Date(a.date))
    .reduce((a, c) => (a.map(e=>e.name).includes(c.name) || a.push(c), a), []).includes(item));

console.log(result);

→ Ссылка
Автор решения: vsemozhebuty

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

const array = [
    {name:"Joe", date:'2018-07-08' },
    {name:"Mars", date:'2018-07-20'},
    {name:"Joe", date:'2018-07-02'},
    {name:"Saturn", date:'2018-07-01'},
    {name:"Joe", date:'2018-07-02'},
    {name:"Mars", date:'2018-07-01'},
];

const result = Object.values(array.reduce(
  (acc, { name, date }) => {
    if (!acc[name] || acc[name].date < date) acc[name] = { name, date };
    return acc;
  },
  {},
));

console.log(result);

→ Ссылка