繁体   English   中英

删除数组中以前的相似条目

[英]de-dupe previous similar entries in an array

假设我有以下对象数组:

[
    {
        status: 'Draft',
        order: 1
    },
    {
        status: 'Accepted',
        order: 2
    },
    {
        status: 'Ordered',
        order: 3
    },
    {
        status: 'Ordered',
        order: 4
    },
    {
        status: 'Sent',
        order: 5
    }
]

我想知道,我想对这个数组中的对象进行重复数据删除,但只对具有重复状态的“最旧”object 进行重复数据删除,也就是说,对于上面的数组,我想以以下去重复结束 -欺骗数组:

[
    {
        status: 'Draft',
        order: 1
    },
    {
        status: 'Accepted',
        order: 2
    },
    {
        status: 'Ordered',
        order: 4
    },
    {
        status: 'Sent',
        order: 5
    }
]

也就是说,状态 Ordered 4 比状态 Ordered 3“更年轻”……而且不仅仅是去重复……这可以扩展到以下内容:

[
    {
        status: 'Draft',
        order: 1
    },
    {
        status: 'Accepted',
        order: 2
    },
    {
        status: 'Ordered',
        order: 3
    },
    {
        status: 'Ordered',
        order: 4
    },
    {
        status: 'Ordered',
        order: 5
    },
    {
        status: 'Confirmed',
        order: 6
    }
]

将导致:

[
    {
        status: 'Draft',
        order: 1
    },
    {
        status: 'Accepted',
        order: 2
    },
    {
        status: 'Ordered',
        order: 5
    },
    {
        status: 'Confirmed',
        order: 6
    }
]

NB有一个警告,我实际上没有 object 中的订单密钥,这纯粹是为了演示目的,以证明我对这个问题的意思。

非常简单减少 function。基本上我们创建一个 object(每个键只能有一个值)。 数组中具有特定状态的“最后”条目将被保留。

 const input = [ { status: 'Draft', order: 1 }, { status: 'Accepted', order: 2 }, { status: 'Ordered', order: 3 }, { status: 'Ordered', order: 4 }, { status: 'Ordered', order: 5 }, { status: 'Confirmed', order: 6 } ]; const output = Object.values(input.reduce((a, e) => { a[e.status] = e; return a; }, {})); console.log(output);

带有 Map 的单线:

 const arr = [ { status: 'Draft', order: 1 }, { status: 'Accepted', order: 2 }, { status: 'Ordered', order: 3 }, { status: 'Ordered', order: 4 }, { status: 'Ordered', order: 5 }, { status: 'Confirmed', order: 6 } ]; const deduped = [...new Map(arr.map(o => [o.status, o])).values()]; console.log(deduped);

JS 本身不包含 dedup/distinct function,因此您必须自己制作,例如使用过滤器检查重复项

过滤器的标准回调是(item, index, array)

这意味着你可以做

filter((item,idx,arr)=> arr.findIndex(other=>areEqual(item,other)) != idx)

这读作删除它们以前存在于数组中的所有元素,因为 findIndex 返回第一个匹配项的位置,所以如果它们当前索引不等于它那么它不是第一个匹配项

使用 findindex 而不是 indexOf 的原因是 findIndex 允许您指定如何检查是否相等

这是 areEqual 回调进来的地方,它需要 2 个项目,如果它们相等则返回 true

所以可能是

areEqual(a,b){
    return a.field === b.field
}

当然,这对于 a.field === b.field 来说太过分了,可以重写为

filter((item,idx,arr)=> arr.findIndex(other=>item.field === other.field) != idx)

但是您指出您的相等性测试可能比单个已知字段更复杂,因此对 areEqual 的回调允许更复杂的逻辑

不幸的是没有 findLastIndex 但在过滤之前简单地反转数组将解决这个问题,然后反转结果以重新获得原始顺序

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM