![](/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.