ES6 - 从对象数组中删除重复项

And*_*ndy 12 javascript reduce dictionary unique filter

假设一个对象数组如下:

const listOfTags = [
    {id: 1, label: "Hello", color: "red", sorting: 0},
    {id: 2, label: "World", color: "green", sorting: 1},
    {id: 3, label: "Hello", color: "blue", sorting: 4},
    {id: 4, label: "Sunshine", color: "yellow", sorting: 5},
    {id: 5, label: "Hello", color: "red", sorting: 6},
]
Run Code Online (Sandbox Code Playgroud)

如果标签和颜色相同,则重复输入.在这种情况下,id = 1且id = 5的对象是重复的.

如何过滤此数组并删除重复项?

我知道解决方案,您可以使用以下内容过滤一个键:

const unique = [... new Set(listOfTags.map(tag => tag.label)]
Run Code Online (Sandbox Code Playgroud)

但是多个键呢?

根据评论中的要求,这里是期望的结果:

[
    {id: 1, label: "Hello", color: "red", sorting: 0},
    {id: 2, label: "World", color: "green", sorting: 1},
    {id: 3, label: "Hello", color: "blue", sorting: 4},
    {id: 4, label: "Sunshine", color: "yellow", sorting: 5},
]
Run Code Online (Sandbox Code Playgroud)

Nin*_*olz 15

您可以Set在闭包中使用进行过滤。

const
    listOfTags = [{ id: 1, label: "Hello", color: "red", sorting: 0 }, { id: 2, label: "World", color: "green", sorting: 1 }, { id: 3, label: "Hello", color: "blue", sorting: 4 }, { id: 4, label: "Sunshine", color: "yellow", sorting: 5 }, { id: 5, label: "Hello", color: "red", sorting: 6 }],
    keys = ['label', 'color'],
    filtered = listOfTags.filter(
        (s => o => 
            (k => !s.has(k) && s.add(k))
            (keys.map(k => o[k]).join('|'))
        )
        (new Set)
    );

console.log(filtered);
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)

  • 对于一些不太喜欢闭包的开发人员来说,对代码的一些评论会很有帮助。这是一个很好的例子,闭包非常适合。对于那些感兴趣的人:“listOfTags.filter”中的第一个函数是一个工厂函数,它会立即使用新的空集“s”进行调用。在过滤完成之前,“s”将可用。第二个函数是实际的过滤函数。每个对象“o”都会调用它并返回一个布尔值。(在这种情况下,另一个闭包函数使用对象“o”的串联字段作为参数进行实际的过滤器测试。) (11认同)
  • 应该用更干净的代码编写,使用单个字符非常混乱 (2认同)

小智 9

const listOfTags = [
    {id: 1, label: "Hello", color: "red", sorting: 0},
    {id: 2, label: "World", color: "green", sorting: 1},
    {id: 3, label: "Hello", color: "blue", sorting: 4},
    {id: 4, label: "Sunshine", color: "yellow", sorting: 5},
    {id: 5, label: "Hello", color: "red", sorting: 6},
]

const unique = [];

listOfTags.map(x => unique.filter(a => a.label == x.label && a.color == x.color).length > 0 ? null : unique.push(x));

console.log(unique);
Run Code Online (Sandbox Code Playgroud)


Seb*_* C. 8

晚了,但我不知道为什么没有人提出更简单的建议:

listOfTags.filter((tag, index, array) => array.findIndex(t => t.color == tag.color && t.label == tag.label) == index);
Run Code Online (Sandbox Code Playgroud)


cha*_*tfl 5

一种方法是创建一个对象(或 Map),它使用 2 个值的组合作为键和当前对象作为值,然后从该对象中获取值

const listOfTags = [
    {id: 1, label: "Hello", color: "red", sorting: 0},
    {id: 2, label: "World", color: "green", sorting: 1},
    {id: 3, label: "Hello", color: "blue", sorting: 4},
    {id: 4, label: "Sunshine", color: "yellow", sorting: 5},
    {id: 5, label: "Hello", color: "red", sorting: 6},
]

const uniques = Object.values(
  listOfTags.reduce((a, c) => {
    a[c.label + '|' + c.color] = c;
    return a
  }, {}))

console.log(uniques)
Run Code Online (Sandbox Code Playgroud)