javascript - JS - 合并至少共享一个共同值的数组

标签 javascript arrays

如果我有以下数组:

var myArr = [[0, 1, 2], [1, 2, 6], [9, 10], [10, 11], [11, 12], [13]];

如何合并至少共享一个公共(public)值的数组以产生以下输出?

var myMergedArr = [[0, 1, 2, 6], [9, 10, 11, 12], [13]];

谢谢!

注意:它们并不总是被很好地排序,并且当所有内容都被排序时,共享值可能并不总是开始/结束值。为了清楚起见,我已经订购了上述值。

最佳答案

可以使用空数组(合并)作为起始值来缩减数组。对于 myArray 中的每个数组,existing 被定义为 mergedsubArray 数组,使得每个 subArrayarray 都不为空。

如果找不到这样的数组,existing 将保持未定义状态,并且一个新数组(包含在另一个数组中)将被定义为 existing 并推送到 合并

如果找到多个匹配项(existing.slice(1) 不为空),则需要将它们合并在一起:existing[0] 充当容器,其中所有其他子数组(existing[1..])被合并(没有重复项)。然后,需要在 merged 中找到这些进一步的匹配项并将其删除,因为它们已经被合并了。这保证了多个数组如果属于在一起就会被合并,即使它们之前没有合并。

然后,array 中的每一项(如果尚未包含)都会被推送到 existing[0] 中。最后,返回merged。然后 reduce 的下一次迭代可以再次将 merged 作为第一个参数,并继续处理 myArr 中的下一个数组。

这是 ES6 代码。如果需要,您可以将其转译并填充到 ES5。

var myArr = [
    [0, 1, 2],
    [1, 2, 6],
    [9, 10],
    [10, 11],
    [11, 12],
    [13]
  ],
  myMergedArr = myArr.reduce((merged, array) => {
    let existing = merged.filter((subArray) => subArray.filter((subItem) => array.includes(subItem)).length);

    if (!existing.length) {
      existing = [
        []
      ];
      merged.push(existing[0]);
    }
    else {
      existing.slice(1).forEach((furtherArray) => {
        furtherArray.forEach((item) => {
          if (!existing[0].includes(item)) {
            existing[0].push(item);
          }
        });
        merged.splice(merged.findIndex((subArray) => furtherArray == subArray), 1);
      });
    }

    array.forEach((item) => {
      if (!existing[0].includes(item)) {
        existing[0].push(item);
      }
    });

    return merged;
  }, []);

console.log(myMergedArr);

<小时/>

第二个片段是相同的代码,但数组已更改。这是为了证明即使子数组不按顺序排列,此脚本也能正常工作:首先 [0, 1, 2] 独立,然后 [3, 4 , 5] 也是独立的 — 两者仍然分开。仅稍后 [2, 3] 才会导致所有先前的数组合并为一个。

var myArr = [
    [0, 1, 2],
    [3, 4, 5],
    [2, 3],
    [7, 9],
    [9, 10],
    [13]
  ],
  myMergedArr = myArr.reduce((merged, array) => {
    let existing = merged.filter((subArray) => subArray.filter((subItem) => array.includes(subItem)).length);

    if (!existing.length) {
      existing = [
        []
      ];
      merged.push(existing[0]);
    }
    else {
      existing.slice(1).forEach((furtherArray) => {
        furtherArray.forEach((item) => {
          if (!existing[0].includes(item)) {
            existing[0].push(item);
          }
        });
        merged.splice(merged.findIndex((subArray) => furtherArray == subArray), 1);
      });
    }

    array.forEach((item) => {
      if (!existing[0].includes(item)) {
        existing[0].push(item);
      }
    });

    return merged;
  }, []);

console.log(myMergedArr);

关于javascript - JS - 合并至少共享一个共同值的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39552694/

相关文章:

javascript - 使用 FRP 管理状态

java 方法中的一维数组设置

java - 如何创建可打包的二维可打包数组?

java - 在 Java 中我可以缩小数组以节省内存吗?

java - 为什么无法获取指定条件的数组索引?

javascript - AngularJS $resource @前缀参数

javascript - 放置区框外的表单字段

javascript - 类似 iPhoneX 通过拖动显示/隐藏菜单/容器

javascript - jQuery 克隆表行但页面上有多个表

c - "array"和 "&array[0]"可以完全互换吗?