如何在javascript中使用两个数组列表来提高比较和选择对象的性能

时间:2017-05-30 19:09:00

标签: javascript arrays underscore.js lodash javascript-objects

嗨我有两组数组对象,我需要选择只有mrp更高 在更新列表中。我可以使用lodash map和Find函数获得Result。它花了10到15 k记录的更多时间。无论如何都要提高性能。这是我的代码。

var ExisitingData=[{"isActive" : true, 
    "barcode" : "8908001921015",     
    "mrp" : 2000, 
},
{"isActive" : true, 
    "barcode" : "8908001921015",     
    "mrp" : 1000, 
}
....15k]


var updatedData=[{"isActive" : true, 
    "barcode" : "8908001921015",     
    "mrp" : 4000, 
},
{"isActive" : true, 
    "barcode" : "8908001921015",     
    "mrp" : 1000, 
}
....15k]

var newData=[]
 _.map(result1, function (item) {
                var updateRecord = _.find(data3, {'barcode': item['barcode']});
                if (updateRecord) {
                    if (item['mrp'] > updateRecord['mrp']) {
                        newData.push(item);

                    }
                }
            });

2 个答案:

答案 0 :(得分:1)

您可以使用纯JavaScript有效地执行此操作,并且它不需要更多代码。我建议使用ES6 Map按条形码键入 updatedData ,这样您就可以快速查找 existingData 中的每个条形码。在这里,我将Map作为this对象提供给filter

let newData = existingData.filter(function (o) {
    return o.mrp > this.get(o.barcode);
}, new Map(updatedData.map( o => [o.barcode, o.mrp] )) );

const existingData = [{
    "isActive" : true, 
    "barcode" : "8908001921015",     
    "mrp" : 2000, 
}, {
    "isActive" : true, 
    "barcode" : "2699001592228",
    "mrp" : 1000,
}];

const updatedData = [{
    "isActive" : true, 
    "barcode" : "2699001592228",     
    "mrp" : 4000, 
}, {
    "isActive" : true, 
    "barcode" : "8908001921015",     
    "mrp" : 1000, 
}];

let newData = existingData.filter(function (o) {
    return o.mrp > this.get(o.barcode);
}, new Map(updatedData.map( o => [o.barcode, o.mrp] )) );

console.log(newData);

所以这会迭代第二个列表一次(为了创建Map),并迭代第一个列表一次(为了过滤它)。 Map#get方法以恒定时间运行,因此此代码在 O(n + m)时间运行,其中 n m 是两个数组的大小。

答案 1 :(得分:0)

这似乎运行得更快(对我来说几乎是瞬间的15k项目):

// group the two lists by barcode
const grouped = _.groupBy([...ExisitingData, ...updatedData], 'barcode');

// ignore any barcode that was added or removed
const pairs = _.filter(grouped, pair => pair.length === 2);

// filter by mrp change
const filteredPairs = _.filter(pairs, ([existingRecord, updatedRecord]) => updatedRecord.mrp > existingRecord.mrp);

// map to items
const newData = _.map(filteredPairs, ([existingRecord, updatedRecord]) => updatedRecord);

如果您还要包含已添加的新项目(即条件代码存在于updatedData列表中但不包含在ExisitingData中),您可以将它们包括在内:

const addedItems = _.differenceBy(updatedData, ExisitingData, 'barcode');
const newData2 = [...newData, ...addedItems];

非ES6版本(对我来说已经有一段时间了,希望我能做到这一点):

// group the two lists by barcode
var grouped = _.groupBy(ExisitingData.concat(updatedData), 'barcode');

// ignore any barcode that was added or removed
var pairs = _.filter(grouped, function(pair) {
  return pair.length === 2;
});

// filter by mrp change
var filteredPairs = _.filter(pairs, function(pair) {
  return pair[1].mrp > pair[0].mrp;
});

// map result to item objects
var newData = _.map(filteredPairs, function(pair) {
  return pair[1];
});

包括新项目:

var addedItems = _.differenceBy(updatedData, ExisitingData, 'barcode');
var newData2 = newData.concat(addedItems);