我想在JavaScript中合并两个Array。不幸的是,我使用的特定数据的比较是昂贵的。使用最少量的比较将我合并到列表的最佳算法是什么?
编辑:我应该注意这两个数组是排序的,我希望合并的内容被排序,并且只有唯一的值。
编辑:根据要求,我会给你我当前的代码,但它确实无济于事。
// Merges arr1 and arr2 (placing the result in arr1)
merge = function(arr1,arr2) {
if(!arr1.length) {
Array.prototype.push.apply(arr1,arr2);
return;
}
var j, lj;
for(var s, i=0, j=0, li=arr1.length, lj=arr2.length; i<li && j<lj;) {
s = compare(arr1[i], arr2[j]);
if(s<0) ++i;
else if(s==0) ++i, ++j;
else arr1.splice(i,0, arr2[j++]);
}
if(j<lj) Array.prototype.push.apply(arr1, arr2.slice(j));
};
答案 0 :(得分:1)
这正是merge sort在合并步骤中所做的事情,只需添加一些重复元素即可删除。这是算法:
function merge(left,right)
var list result
while length(left) > 0 and length(right) > 0
if first(left) ≤ first(right)
append first(left) to result
left = rest(left)
else
append first(right) to result
right = rest(right)
end while
if length(left) > 0
append left to result
else
append right to result
return result
答案 1 :(得分:1)
这是一个制作数组unique的函数:
Array.prototype.unique = function () {
var r = new Array();
o:for(var i = 0, n = this.length; i < n; i++)
{
for(var x = 0, y = r.length; x < y; x++)
{
if(r[x]==this[i])
{
continue o;
}
}
r[r.length] = this[i];
}
return r;
}
要合并数组,您可以这样做:
var MainArray= arr1.concat(arr2);
然后删除重复项:
var MainArray= MainArray.unique();
然后排序:
var MainArray= MainArray.sort(); //Or you own sort if you have one
我认为这听起来像你正在寻找的那样,但它可能取决于数据的数量和类型。
答案 2 :(得分:0)
这似乎是我使用地图进行比较而不是比较功能。它导致更多的循环,但通常比比较更昂贵。这用于右连接具有name属性的对象数组。它还有一个独特的问题,即必须修改现有阵列,而不是创建新阵列和分配。有些参考D3和强制节点。
function merge(right,left) {
var map_right = {},
map_left = {};
right.forEach(function(n) {
map_right[n.name] = n;
});
left.forEach(function(n) {
map_left[n.name] = n;
});
for(var n in map_left) {
if (map_right[n] === undefined) {
left.splice(nodes.indexOf(map_b[n]),1);
}
}
right.forEach(function (n) {
if (map_left[n.name] === undefined) {
left.push(n);
}
});
}