![](/img/trans.png)
[英]Is there a way to de-dupe a javascript array and combine values of the data?
[英]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.