删除 javascript 数组中重复对象的所有实例

Remove all instances of duplicate objects in a javascript array

我正在尝试删除 javascript 数组中重复对象的所有实例。下面的辅助函数可以很好地删除重复项并保留 1 个实例,但我想通过删除所有实例来基本上取消与另一个对象具有相等 属性 的任何对象的资格。

function removeDuplicates(data, key) {
    return [
        ... new Map(
            data.map(x => [key(x), x])
        ).values()
    ]
}

未清理数组示例:

[
  {
    name: 'name1',
    value: 15
  },
  {
    name: 'name2',
    value: 16
  },
  {
    name: 'name3',
    value: 17
  },
  {
    name: 'name1',
    value: 18
  }
]

从上面的辅助函数返回:

[
  {
    name: 'name1',
    value: 15
  },
  {
    name: 'name2',
    value: 16
  },
  {
    name: 'name3',
    value: 17
  }
]

我希望返回的内容:

[
  {
    name: 'name2',
    value: 16
  },
  {
    name: 'name3',
    value: 17
  }
]

如有任何想法,我们将不胜感激!

假设您的意图是以这种方式调用上面的函数:removeDuplicates(data, (x) => x.name),这是我的实现

function removeDuplicates(data, key) {
    return data.filter((o, idx) => {
        const remainingData = [...data.slice(0, idx), ...data.slice(idx + 1)];
        return !remainingData.some(o2 => key(o) === key(o2));
    });
}

基本上,对于数据数组中的每个元素,我检查剩余的值,看是否有另一个元素具有相同的“键”。我使用 "some" method for Javascript arrays 来测试这个。过滤器函数仅返回未通过此测试的值。


正如一些人所说 - 这不是最有效的解决方案,所以让我提供一个更好的实施方案:

function removeDuplicatesBetter(data, key) {
    return data.filter((o, idx) => {
        return !data.some((o2, idx2) => idx !== idx2 && key(o) === key(o2));
    });
}

这里是 Repl.it 演示解决方案:https://replit.com/@VehpuS/removeDuplicates

function removeDuplicates(arr, key) {
    const duplicates = arr.reduce((seen, obj) => ((seen[obj[key]] = seen.hasOwnProperty(obj[key])), seen), {});
    return arr.filter((obj) => !duplicates[obj[key]]);
}

//Usage: 
const input = [
    {
        name: "name1",
        value: 15,
    },
    {
        name: "name2",
        value: 16,
    },
    {
        name: "name3",
        value: 17,
    },
    {
        name: "name1",
        value: 18,
    },
];

const output = removeDuplicates(input, "name");

console.log(output);
//output: [ { name: 'name2', value: 16 }, { name: 'name3', value: 17 } ]