【问题标题】:Remove duplicates from an array of objects based on time created根据创建的时间从对象数组中删除重复项
【发布时间】:2021-06-29 00:26:55
【问题描述】:

我有一个对象数组,并且有一些重复的对象

const data = [
{
    "id": "1011",
    "name": "abc",
    "Dob": "3/2/11",
    "timeCreated": "16:03:41"
},
{
    "id": "1012",
    "name": "xys",
    "Dob": "6/5/12",
    "timeCreated": "01:05:21"
},
{
    "id": "1011",
    "name": "xyz",
    "Dob": "3/2/11",
    "timeCreated": "17:03:41"
},
{
    "id": "1011",
    "name": "xyz",
    "Dob": "3/2/11",
    "timeCreated": "15:03:41"
}
]

我正在使用 some() 删除数组中的重复项

let arr = [];
data.forEach(obj => {
  if (!arr .some(o => o.id === obj.id)) {
    arr.push({ ...obj})
  }
});   

我需要帮助过滤它并仅保留基于“timeCreated”的最新对象

所以数据看起来像这样:

{
    "id": "1012",
    "name": "xys",
    "Dob": "6/5/12",
    "timeCreated": "01:05:21"
},
{
    "id": "1011",
    "name": "xyz",
    "Dob": "3/2/11",
    "timeCreated": "17:03:41"
},
]

【问题讨论】:

  • Dob中的日期,不算吗?
  • 我的实际数据不包括 Dob 我只是把它放在因为我想不出其他任何东西,但我唯一需要帮助的是确保它删除旧日期并保留日期最近的那个。

标签: javascript typescript react-native


【解决方案1】:

你可以这样做:

const data = 
  [ { id: '1011', name: 'abc', Dob: '3/2/11', timeCreated: '16:03:41' } 
  , { id: '1012', name: 'xys', Dob: '6/5/12', timeCreated: '01:05:21' } 
  , { id: '1011', name: 'xyz', Dob: '3/2/11', timeCreated: '17:03:41' } 
  , { id: '1011', name: 'xyz', Dob: '3/2/11', timeCreated: '15:03:41' } 
  ] 

const arr = data.reduce((result,obj)=>
  {
  let row = result.find(x=>x.id===obj.id)
  if (!row)
         result.push({...obj})
  else if (row.timeCreated < obj.timeCreated)
         Object.assign(row,obj)
  return result
  },[])

console.log( arr )
.as-console-wrapper {max-height: 100%!important;top:0 }

【讨论】:

    【解决方案2】:

    聚会迟到了,但这里有一个更短、可能更快、更有效的解决方案,它只涉及排序和过滤操作

    let tmp=[], arr = data.sort((a, b) => +b.timeCreated.replaceAll(':', '') - +a.timeCreated.replaceAll(':', ''))
                .filter(o => (!tmp.includes(o.id) && tmp.push(o.id)));
    

    它是如何工作的:实际上很简单。它首先按 timeCreated 降序对数组进行排序。它通过(即时)将“HH:MM:SS”字符串转换为数字 HHMMSS (+b.timeCreated.replaceAll(':', '')),然后进行比较来实现这一点。然后它获取排序后的数组并通过临时数组tmp 对其进行过滤,该临时数组存储每次迭代的 id - 如果 id 已经在其中(根据 timeCreated 我们知道这是最新的),我们将其过滤掉。这一切都由极其简单的三元组处理:.filter(o =&gt; (!tmp.includes(o.id) &amp;&amp; tmp.push(o.id)),它表示 如果我们已经看到了该 id,则返回 false,否则记下它

    为什么它很酷 - 对于大多数用例(小型数据集),there isn't a significant difference 在函数迭代器之间,如 map, reduce, forEach, filter, sort - 但是这是开箱即用的想法。与其构建数据集并减少它们,不如先巧妙地将其切成大小 - 仅使用 2 个操作。

    const data = [{ id: '1011', name: 'abc', Dob: '3/2/11', timeCreated: '16:03:41' }, { id: '1012', name: 'xys', Dob: '6/5/12', timeCreated: '01:05:21' }, { id: '1011', name: 'xyz', Dob: '3/2/11', timeCreated: '17:03:41' }, { id: '1011', name: 'xyz', Dob: '3/2/11', timeCreated: '15:03:41' }]
    let tmp=[], arr = data.sort((a, b) => +b.timeCreated.replaceAll(':', '') - +a.timeCreated.replaceAll(':', '')).filter(o => (!tmp.includes(o.id) && tmp.push(o.id)));
        
    console.log(arr)

    【讨论】:

    • 你能简单解释一下filter中发生了什么吗?
    • @SamLock 我用一个(有点自我祝贺的)解释更新了我的答案:)
    猜你喜欢
    • 2012-05-17
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 2020-06-29
    • 2015-05-13
    • 1970-01-01
    • 2017-04-10
    相关资源
    最近更新 更多