消除对象数组中的重复项

4

我试图消除对象数组中的重复项。我希望我的代码是线性的,因此我使用哈希表:

output = Array.from(new Set(output.map(e => e.company)))
  .map(company => { return output.find(e => e.company === company) })

这段代码适用于这个对象数组:
let output = [
  { company: 'sony'},
  { company: 'sony'},
  { company: 'apple'}
]

然而问题在于我想要重复使用这段代码,因此我希望将其移动到一个函数中,该函数会接受 output 数组和 company 字符串。我不知道如何实现,我尝试过像这样:

const uniq = (array, key) => {
  return Array.from(new Set(array.map( e => e[key] )))
    .map(key => { return array.find(e => e[key] === key) })
}

但是这返回一个包含两个未定义值的数组。


另外一件事是,对于如此微不足道的任务来说,这段代码相当复杂。难道没有更简单的方法在不损失性能的情况下完成同样的任务吗?

6个回答

3

这个单行代码适用于任意对象,不一定是键值对:

let uniqBy = (a, key) => [...new Map(a.map(x => [x[key], x]).reverse()).values()];

//

let data = [
    {company: 'sony', more: 1},
    {company: 'apple', more: 1},
    {company: 'sony', more: 2},
    {company: 'sony', more: 3},
    {company: 'apple', more: 3},
]

console.log(uniqBy(data, 'company'))

如果您不关心结果的顺序,也可以跳过 .reverse()


我认为这个和@Nina Scholz是我个人最喜欢的解决方案。 - BT101
看起来它只是稍微快了一点,但相当微不足道。 - BT101

2
您可以将唯一值映射并创建一个新对象。

const 
    unique = (array, key) => Array.from(new Set(array.map(o => o[key])), value => ({ [key]: value }));

var output = [{ company: 'sony'}, { company: 'sony'}, { company: 'apple'}];

console.log(unique(output, "company"));


1
你遇到了命名冲突,只需要将第二个 key 重命名即可:

let input = [{ company: "sony" }, { company: "sony" }, { company: "apple" }];

const uniq = (array, key) => {
  return Array.from(new Set(array.map(e => e[key]))).map(key1 => {
    //                                                   ^^^^
    return array.find(e => e[key] === key1);
    //                                ^^^^
  });
};

const result = uniq(input, "company");

console.log(result);


1

我认为问题在于你正在覆盖.map()回调函数中的key定义。使用一个单独的变量名称作为回调参数似乎可以满足你的需求:

let output = [
  { company: 'sony'},
  { company: 'sony'},
  { company: 'apple'}
]
const uniq = (array, key) => {
  return Array.from(new Set(array.map( e => e[key] )))
    .map(x => { return array.find(e => e[key] === x) })
}

console.log(uniq(output, "company"));


1

你需要将第二个map参数重命名为除key以外的其他名称,否则find内部的key将不是传递给函数的参数key

let output = [
  { company: 'sony'},
  { company: 'sony'},
  { company: 'apple'}
]

const uniq = (array, key) => {
  return Array.from(new Set(array.map( e => e[key] )))
    .map(k => { return array.find(e => e[key] === k) })
}

console.log(uniq(output, 'company'));


0
如果你被允许使用 Lodash,那么有一种简单的方法可以消除重复项。
_.uniqBy(your_data, 'company');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接