使用平面列表并寻找一种有效的方法来组合列表中的元素,同时删除重复的元素。每个元素都有一个唯一的键值,以知道它是否重复。
我当前的实现使用concat函数:
Array.prototype.unique = function() {
var a = this.concat();
for(var i=0; i<a.length; ++i) {
for(var j=i+1; j<a.length; ++j) {
if(a[i].key === a[j].key)
a.splice(j--, 1);
}
}
return a;
};
const OldArray = this.state.data;
const NewArray = [] //contains values we loaded in
const FinalArray = OldArray.concat(NewArray).unique();
//Update the State
this.setState({
data: FinalArray
)}
这确实有效,但是每次这个函数运行它的效率至少为n^2,这看起来很糟糕。有更好的办法吗?我觉得一定有..
最佳答案
您可以使用Array#reduce创建一个具有唯一值的映射,然后将其扩展回一个数组这将获得具有相同键的对象的第一个外观。
const union = (arr1, arr2, key) => [... // spread to an array
arr1.concat(arr2) // concat the arrays
.reduce((m, o) => m.has(o[key]) ? m : m.set(o[key], o), new Map) // reduce to a map by value of key
.values()]; // get the values iterator
const OldArray = [{ a: 1, v: 1 }, { a: 2 }]
const NewArray = [{ a: 1, v: 100 }, { a: 3 }]
const FinalArray = union(OldArray, NewArray, 'a')
console.log(FinalArray);
@4castle建议的另一个选项是使用array map初始化映射。但是,这将采用具有相同键的对象的最后外观。在初始化映射之前,始终可以将数组反转。
const union = (arr1, arr2, key) => [... // spread to an array
new Map(arr1.concat(arr2).map(o => [o[key], o])) // concat and initialize the map
.values()]; // get the values iterator
const OldArray = [{ a: 1, v: 1 }, { a: 2 }]
const NewArray = [{ a: 1, v: 100 }, { a: 3 }]
const FinalArray = union(OldArray, NewArray, 'a')
console.log(FinalArray);
关于javascript - 组合阵列以消除重复项的最有效方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46869330/