在Javascript中,基于交叉点累计合并数组,不存在重复。

问题描述 投票:0回答:1

我的数据是这样的聚类 [[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
    }
  }
}

结果是集群数组没有变化. 我想,如果我能找到一种方法来递归运行联合操作(当满足交集条件时),这个方法就会奏效。或者,也许还有更好的方法?

javascript array-merge
1个回答
1
投票

你可以通过以下方法来实现 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);

1
投票

这可能(我没有真正测试过,就当是你开始研究的一个想法)可行。

你并不真正需要递归,因为你处理的只是一个嵌套层。如果你有一个大的数据集,要小心这个的性能不好。

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);
© www.soinside.com 2019 - 2024. All rights reserved.