我的数据是这样的聚类 [[1, 2, 3], [0, 2], [2, 4], [6, 7]]
. 我想合并共享项目的数组,而不存在重复。例如,我想从上面的数据中得到的结果将是 [[1, 2, 3, 0, 4], [6, 7]]
.
我的方法是在数组中循环,当找到交集时,形成两个数组的联合。这是我试过的方法。
let clusters = [[1, 2, 3], [0, 2], [2, 4], [6, 7]];
let len = clusters.length;
let i, j;
for (i = 0; i < len; i++) {
for (j = i+1; j < len; j++) {
if (clusters[i].filter(x => clusters[j].includes(x))) {
clusters[i] = [...new Set([...this.clusters[i], ...this.clusters[j]])]; // this won't work
}
}
}
结果是集群数组没有变化. 我想,如果我能找到一种方法来递归运行联合操作(当满足交集条件时),这个方法就会奏效。或者,也许还有更好的方法?
你可以通过以下方法来实现 Array.reduce
,将数组从 clusters
到输出数组中的集合中,或者如果输出中的某一个集合中已经存在一个值,则合并,完成后再从集合转换回数组。
let clusters = [
[1, 2, 3],
[0, 2],
[2, 4],
[6, 7]
];
let result = clusters.reduce((c, a) => {
for (i = 0; i < c.length; i++) {
if (a.some(v => c[i].has(v))) {
a.forEach(v => c[i].add(v));
return c;
}
}
c.push(new Set(a));
return c;
}, [])
.map(s => Array.from(s));
console.log(result);
这可能(我没有真正测试过,就当是你开始研究的一个想法)可行。
你并不真正需要递归,因为你处理的只是一个嵌套层。如果你有一个大的数据集,要小心这个的性能不好。
var a=[[1, 2, 3], [0, 2], [2, 4], [6, 7]];
function match(a,b) {
//if you meant _at least_ one match between two elements
for(var i=0;i<a.length;i++) if(b.indexOf(a[i])>0) return true;
return false;
}
function combine(a,b) {
var c=[];
for(var i=0;i<a.length;i++) if(c.indexOf(a[i])<0) c.push(a[i]);
for(var i=0;i<b.length;i++) if(c.indexOf(b[i])<0) c.push(b[i]);
return c;
}
while(1) {
var found=false;
for(var i=0;i<a.length;i++) {
for(var j=0;j<a.length;j++) {
if(i==j) continue;
//if a match is found, merge the two elements and start over
if(match(a[i],a[j])) {
a[i]=combine(a[i],a[j]);
a.splice(j,1);
found=true;
break;
}
}
if(found) break;
}
//repeat until no matches were found
if(!found) break;
}
console.log(a);