簡體   English   中英

JS-過濾對象數組以查找一個屬性的重復項,並根據另一個屬性確定要保留的對象

[英]JS - Filter an array of objects for duplicates of one property, and decide which object to keep based on another property

嘗試通過消除具有另一個對象中已經存在的特定屬性的對象來過濾對象數組(重復項)。 決定刪除哪個對象應該基於另一個屬性。

示例:對於一組看起來像這樣的對象,目標是過濾所有“用戶”重復項,並保留具有最舊“日期”屬性的對象。

const arr = [
    {user: 'Alex', date: '1540801929945'},
    {user: 'Bill', date: '1640801929946'},
    {user: 'Carl', date: '1740801929947'},
    {user: 'Alex', date: '1840801929948'},
]

預期結果:

filteredArr = [
    {user: 'Alex', date: '1540801929945'},
    {user: 'Bill', date: '1640801929946'},
    {user: 'Carl', date: '1740801929947'},
]

我管理了僅用於保留唯一對象的基本過濾。

const filteredArr = arr.reduce((unique, o) => {
    if(!unique.some(obj => obj.user === o.user) {
      unique.push(o);
    }
    return unique;
},[]);

盡管我不知道,該怎么做,以便在重復的情況下保留“最舊的”對象,並刪除最新的對象。 非常感謝你的幫助! 非常感謝。

將數組簡化為以user為鍵的對象。 如果用戶不在unique對象中,或者用戶的日期比該日期“早”,則將其添加到對象中。 使用Object.values()將對象轉換為數組。

注意:由於您的日期是字符串,因此在比較時將它們轉換為數字(我使用+運算符 )。

 const array = [{ user: 'Alex', date: '1540801929945' }, { user: 'Bill', date: '1640801929946' }, { user: 'Carl', date: '1740801929947' }, { user: 'Alex', date: '1840801929948' }]; const filteredArray = Object.values(array.reduce((unique, o) => { if(!unique[o.user] || +o.date > +unique[o.user].date) unique[o.user] = o; return unique; }, {})); console.log(filteredArray); 

Map和單循環方法的解決方案

 var array = [{ user: 'Alex', date: '1540801929945' }, { user: 'Bill', date: '1640801929946' }, { user: 'Carl', date: '1740801929947' }, { user: 'Alex', date: '1840801929948' }], filtered = Array.from(array .reduce((m, o) => !m.has(o.user) || m.get(o.user).data > o.date ? m.set(o.user, o) : m, new Map) .values()); console.log(filtered); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

對於排序的數據(按date提前排序),可以使用Set進行過濾。

 var array = [{ user: 'Alex', date: '1540801929945' }, { user: 'Bill', date: '1640801929946' }, { user: 'Carl', date: '1740801929947' }, { user: 'Alex', date: '1840801929948' }], filtered = array .sort(({ date: a }, { date: b }) => a - b) .filter((s => ({ user }) => !s.has(user) && s.add(user))(new Set)); console.log(filtered); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

對於O(N)解決方案,請reduce為一個由user索引的對象,該對象的值是date s-在每次迭代中,如果該user已經存在某個對象,則僅保留最低date 然后,遍歷對象的entries以將其返回到數組中:

 const arr = [ {user: 'Alex', date: '1540801929945'}, {user: 'Bill', date: '1640801929946'}, {user: 'Carl', date: '1740801929947'}, {user: 'Alex', date: '1840801929948'}, {user: 'Carl', date: '1340801929947'}, ]; const arrByUser = arr.reduce((a, { user, date }) => { if (!a[user]) a[user] = date; else if (a[user].localeCompare(date) === 1) a[user] = date; return a; }, {}); const output = Object.entries(arrByUser) .map(([user, date]) => ({ user, date })); console.log(output); 

我相信您實際上需要知道非唯一元素(在您的情況下為名稱“ Alex”的對象)的索引,然后比較它們的日期,以保存較舊的日期。

在這種情況下,Array.prototype.find不會對您有幫助。 但是,Array.prototype.find會有所幫助,因為它需要一個回調,該回調返回一個布爾值(就像“ some”一樣),但它返回與您的回調匹配的元素的索引;如果未找到此類元素,則返回undefined。

試試看,它不會受傷:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM