Как «уникально» массив объектов javascript? - PullRequest
0 голосов
/ 23 июня 2018

Как удалить объекты в массиве, которые совпадают по всем ключам и значениям?Я видел варианты этого вопроса, но только для определенного поля.

Например, при следующем вводе вывод будет выглядеть так:

> var a = [
  {a:1, b:'x'},
  {a:1, b:'y'},
  {a:1, b:'y'},
  {a:2, b:'x'},
  {a:2, b:'y'},
  {a:2, b:'y'},
  {a:2, b:'x'},
  {b:'y', a:2},
  {a:2, b:'y', c:'surprise!'}
]
> blackbox(a)
[
  {a:1, b:'x'},
  {a:1, b:'y'},
  {a:2, b:'x'},
  {a:2, b:'y'},
  {a:2, b:'y', c:'surprise!'}
]

В идеале blackbox isn 't жестко запрограммирован с помощью ключей.

1 Ответ

0 голосов
/ 23 июня 2018

Кстати, вот хак, который у меня сейчас.Он превращает каждый (отсортированный) объект в строку и проверяет, видела ли она эту строку раньше.

В любом случае, должно быть более элегантное решение!

> function uniq(a) {
  var keys = new Set();
  return a.filter(function(row) {
    var key  = Object.entries(row).sort().toString();
    var uniq = !keys.has(key);
    keys.add(key);
    return uniq;
  });
}
> a =
[ { a: 1, b: 'x' },
  { a: 1, b: 'y' },
  { a: 1, b: 'y' },
  { a: 2, b: 'x' },
  { a: 2, b: 'y' },
  { a: 2, b: 'y' },
  { a: 2, b: 'x' },
  { b: 'y', a: 2 },
  { a: 2, b: 'y', c: 'surprise!' },
  { c: 'surprise!', a: 2, b: 'y' } ]
> uniq(a)
[ { a: 1, b: 'x' },
  { a: 1, b: 'y' },
  { a: 2, b: 'x' },
  { a: 2, b: 'y' },
  { a: 2, b: 'y', c: 'surprise!' } ]
> b =
[ { a: { b: 1, c: 2 }, b: 1 },
  { b: 1, a: { c: 2, b: 1 } },
  { a: { b: 1, c: 2 }, b: 2 } ]
> uniq(b) // works because nested objects happen to be identical
[ { a: { b: 1, c: 2 }, b: 1 }, { a: { b: 1, c: 2 }, b: 2 } ] 
> c = 
[ { a: { b: 1, c: 2 }, b: 1 },
  { b: 1, a: { c: 2, b: 1 } },
  { a: { b: 1, c: 2 }, b: 2 },
  { a: { b: 2, c: 1 }, b: 2 } ]
> uniq(c) // fail on nested object
[ { a: { b: 1, c: 2 }, b: 1 }, { a: { b: 1, c: 2 }, b: 2 } ]
...