通过对象属性删除对象数组的doublon

时间:2019-02-21 09:03:21

标签: javascript

我有一个这样的对象数组(按时间戳记升序排列):

[
 {id: 'o3134432S2', tot: '45', type: 'dynamic', timestamp: '2018-04-03'},
 {id: '3566543aa3', tot: '34', type: 'saved', timestamp: '2018-04-03'},
 {id: '4530134a97', tot: '34', type: 'gold', timestamp: '2018-04-04'},
 {id: '234554b333', tot: '42', type: 'saved', timestamp: '2018-04-04'},
 {id: '2463545633', tot: '55', type: 'dynamic', timestamp: '2018-04-05'},
 {id: '5654324566', tot: '13', type: 'saved', timestamp: '2018-04-06'}
]

此数组可能真的很长(超过一千个值),并且每天可能有1金,1保存或两者兼有。 我想每天删除doublon,优先考虑已保存的doublon。 就我而言,它将返回:

[
 {id: '3566543aa3', tot: '34', type: 'saved', timestamp: '2018-04-03'},
 {id: '234554b333', tot: '42', type: 'saved', timestamp: '2018-04-04'},
 {id: '2463545633', tot: '55', type: 'dynamic', timestamp: '2018-04-05'},
 {id: '5654324566', tot: '13', type: 'saved', timestamp: '2018-04-06'}
]

我已经使用了很多时间和foreach来完成某件事,但是这需要5到30秒,而且我敢肯定它会更快。

    function remouveDoublon(originalArray) {
    const filteredSaved = originalArray.filter(forecast => {forecast.type === "saved" })

    const filteredDynamic = forecastProductOrders.filter((forecast) => { return forecast.type === 'dynamic' })
    let exists = false;
    if (filteredSaved.length > 0) {
        filteredSaved.forEach(forecast => {
            exists = false;
            for (var i = 0; i < filteredDynamic.length; i++) {
                if (moment(filteredDynamic[i].timestamp).isSame(moment(forecast.timestamp), 'day') && filteredDynamic[i].supplierProductId === forecast.supplierProductId) {
                    filteredDynamic[i].tot = forecast.tot;
                    exists = true;
                    break;
                }
            }
            if (exists === false) {
                let objToPush = forecast;
                objToPush.type === 'saved';
                filteredDynamic.push(objToPush);
            }
        })
    }
    return filteredDynamic
}

有人对如何做到这一点有想法吗?

非常感谢

3 个答案:

答案 0 :(得分:0)

您可以遍历数组,并使用日期作为键将每个条目保存在字典中。如果条目已经存在,请检查类型并仅在“保存”时进行更新。然后将字典再次转换为列表。这将具有线性运行时。也许像这样

unique = {}
for entry in entries:
    if unique[entry.date] and unique[entry.date].type == "saved":
         continue
    unique[entry.date] = entry

print(list(unique))

答案 1 :(得分:0)

您可以使用此方法,然后根据需要重新按我的时间戳进行排序。

const data = [
 {id: 'o3134432S2', tot: '45', type: 'dynamic', timestamp: '2018-04-03'},
 {id: '3566543aa3', tot: '34', type: 'saved', timestamp: '2018-04-03'},
 {id: '4530134a97', tot: '34', type: 'gold', timestamp: '2018-04-04'},
 {id: '234554b333', tot: '42', type: 'saved', timestamp: '2018-04-04'},
 {id: '2463545633', tot: '55', type: 'dynamic', timestamp: '2018-04-05'},
 {id: '5654324566', tot: '13', type: 'saved', timestamp: '2018-04-06'}
]
let result = data.filter(o => o.type === 'saved')
data.filter(o => o.type !== 'saved').forEach(g => {
  if (result.filter(r => r.timestamp === g.timestamp).length === 0) result.push(g)
})
console.log(result)

答案 2 :(得分:0)

使用Array#Reduce。用时间戳过滤数组。然后在新数组比较类型中存在相同的时间戳。然后仅添加保存的类型对象

var arr = [
 {id: 'o3134432S2', tot: '45', type: 'gold', timestamp: '2018-04-03'},
 {id: '3566543aa3', tot: '34', type: 'saved', timestamp: '2018-04-03'},
 {id: '4530134a97', tot: '34', type: 'gold', timestamp: '2018-04-04'},
 {id: '234554b333', tot: '42', type: 'saved', timestamp: '2018-04-04'},
 {id: '2463545633', tot: '55', type: 'gold', timestamp: '2018-04-05'},
 {id: '5654324566', tot: '13', type: 'saved', timestamp: '2018-04-06'}
];

arr = arr.reduce(function(a,b){
    var ind = a.map(i=>i.timestamp).indexOf(b.timestamp);
    if(ind == -1){
     a.push(b);
    }else{
     a[ind] =  a[ind]['type'] == 'saved'? a[ind]:b;
    }
   return a;
},[])
console.log(arr)