簡體   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