说我有一个初始的对象数组:
var initialData = [
{
'ID': 1,
'FirstName': 'Sally'
},
{
'ID': 2,
'FirstName': 'Jim'
},
{
'ID': 3,
'FirstName': 'Bob'
}
];
然后我获取新数据(另一组对象):
var newData = [
{
'ID': 2,
'FirstName': 'Jim'
},
{
'ID': 4,
'FirstName': 'Tom'
},
{
'ID': 5,
'FirstName': 'George'
}
];
我想将新数据合并为初始数据。但是,我不想覆盖初始数据数组中的任何对象。我只想添加尚不存在的对象。
我知道这些对象是根据其'ID'
键来复制的。
我知道我可以通过遍历新数据,检查是否在初始数据中存在,如果不存在,则推入初始数据来做到这一点。
for ( var i = 0, l = newData.length; i < l; i++ ) {
if ( ! key_exists( newData[i].key, initialData ) ) { // key_exists() is a function that uses .filter() to test.
initialData.push( newData[i] );
}
}
不过,我担心性能。我知道有很多新的ES6处理数组的方式,所以我希望有人有更好的主意。
在忽略新数据重复项的同时,将新数据合并到初始数据中的最佳方法是什么(最好与最佳性能一样)?
答案 0 :(得分:4)
您可以从initialData
创建一组ID,这样可以更快地“检查ID是否已包含在初始数据中”-O(1):
var initialData = [{
'ID': 1,
'FirstName': 'Sally'
},
{
'ID': 2,
'FirstName': 'Jim'
},
{
'ID': 3,
'FirstName': 'Bob'
}
];
var newData = [{
'ID': 2,
'FirstName': 'Jim'
},
{
'ID': 4,
'FirstName': 'Tom'
},
{
'ID': 5,
'FirstName': 'George'
}
];
var ids = new Set(initialData.map(d => d.ID));
var merged = [...initialData, ...newData.filter(d => !ids.has(d.ID))];
console.log(merged);
此方法的最终运行时间为 O(n + m)。
如果您想提高效率,可以考虑遍历newData
并将任何新元素手动推送到最终结果数组中(而不是使用filter
和散布运算符)。
答案 1 :(得分:1)
实际上,如果您对性能感兴趣,可以考虑将initialData
结构更改为以下形式:
var initialData = {
"1": {'FirstName': 'Sally'},
"2": {'FirstName': 'Jim'},
"3": {'FirstName': 'Bob'}
};
换句话说,我们将ID用作对象的键,这将使您O(1)
可以访问数据,而O(1)
可以用于存在测试。您可以使用带有reduce()的下一种方法来获得此结构:
var initialData = [
{'ID': 1, 'FirstName': 'Sally'},
{'ID': 2, 'FirstName': 'Jim'},
{'ID': 3, 'FirstName': 'Bob'}
];
let newInitialData = initialData.reduce((res, {ID, FirstName}) =>
{
res[ID] = {FirstName : FirstName};
return res;
}, {});
console.log(newInitialData);
使用这种新结构,您可以使用O(n)
算法来插入尚不存在的新数据:
var initialData = {
"1": {'FirstName': 'Sally'},
"2": {'FirstName': 'Jim'},
"3": {'FirstName': 'Bob'}
};
var newData = [
{'ID': 2, 'FirstName': 'Jim'},
{'ID': 4, 'FirstName': 'Tom'},
{'ID': 5, 'FirstName': 'George'}
];
newData.forEach(({ID, FirstName}) =>
{
initialData[ID] = initialData[ID] || {FirstName: FirstName};
});
console.log(initialData);
答案 2 :(得分:0)
我认为@slider在接受的答案中提出的替代解决方案是这样的:
#include<cstdio>
void print(const char** x){
printf("%s", x[0]);
}
int main(int argc, char **argv){
if(argc>1){
print((const char **)argv);
}
return 0;
}
//Then compile it as follow:
$ g++ -Wcast-qual test.cpp
//gives the following output:
MCVE.cpp: In function ‘int main(int, char**)’:
MCVE.cpp:5:36: warning: cast from type ‘char**’ to type ‘const char**’ casts away qualifiers [-Wcast-qual]
const char ** q = (const char**) argv;