Google Apps 脚本:当两个数组匹配时合并数组

Google Apps Script: Combine Arrays When there is A Match Between Both Arrays

背景

我有两个阵列(阵列 1 和阵列 2)。它们都共享一个 ID 类型(数组 1 的第 2 列和数组 2 的第 0 列)。我只想在该 ID 中存在匹配项时才垂直组合两个数组。

起始数组:

array1 = [[AB2C, Red, 113]       <--Match
          [BE4F, Green,164]
          [AE3G, Blue, 143]];    <--Match

array2 = [[143, FabricB2, W5]    <--Match
          [189, FabricC9, W4]
          [113, FabricA3, W5]];  <--Match

所需的结尾数组

array3 = [[AB2C, Red, 113, FabricA3, W5]
          [AE3G, Blue, 143, FabricB2, W5]];

方法论

在我看来最有效的方法是:

  1. 创建一个空数组。
  2. 如果 ID 列与数组 2 中的数据匹配,则将数组 1 的数据推送到数组 3。
  3. 将数组 2 的数据推送到数组 3,其中 ID 列与数组 3 匹配。我们还应该只添加数组 2 的列 1 和列 2,这样我们就不会复制 ID 列。

我试过的

对于第 2 步,我一直在尝试使用如下所示的推送和映射组合将数组 1 推送到数组 3,但它无法正常工作。我的意图是将数组 1 的每一行 运行 遍历数组 2 的每一行以检查是否匹配;如果有匹配项,则推送到数组 3。

对于第 3 步,我的想法是获取数组 3 的第 2 列的每一行,运行 它遍历数组 2 的第 0 列的每一行,并在找到匹配项时,将它们连接到数组 3。为了达到这个目的,我从来没有通过第 2 步的等式。

非常感谢您的帮助!

array1 = [[AB2C, Red, 113]
          [BE4F, Green,164]
          [AE3G, Blue, 143]];

array2 = [[143, FabricB2, W5]
          [189, FabricC9, W4]
          [113, FabricA3, W5]];

array3 = [];

array3.push(array1.map( function(e) { return e[2] == array2.map ( function (f) { return f[0] } ) }));

我认为这应该对你有用:

let array1 = [['AB2C', 'Red', 113], ['BE4F', 'Green',164], ['AE3G', 'Blue', 143]];

let array2 = [[143, 'FabricB2', 'W5'], [189, 'FabricC9', 'W4'], [113, 'FabricA3', 'W5']];

let array3 = []
array1.forEach(i => {
  let match = i[2]
  array2.forEach(j => {
    if(j[0] === match) {
      array3.push([...i, j[1], j[2]])
    }
  })
})

console.log(array3)

Sandbox Link

array1 = [
  ['AB2C', 'Red', 113],
  ['BE4F', 'Green', 164],
  ['AE3G', 'Blue', 143],
];

array2 = [
  [143, 'FabricB2', 'W5'],
  [189, 'FabricC9', 'W4'],
  [113, 'FabricA3', ' W5'],
];


const res = array1
  .map(x => array2
    .filter(y => y[0] === x[2])
    .map(y => [x[0], x[1], ...y]))
  .flatMap(x => x)

console.log(res)

这是您可能感兴趣的另一种方法。

现在我们在 Apps 脚本中有了 V8 运行时间,您可以利用像 AlaSQL 这样的第 3 方库来执行复杂的 SQL 查询。

只需将最新版本的 AlaSQL (full or minified) 复制并粘贴到您的 Apps 脚本项目中自己的脚本文件中。

然后你可以运行这样查询:

const arr1 = [
  ['AB2C', 'Red', 113],
  ['BE4F', 'Green', 164],
  ['AE3G', 'Blue', 143],
].map( ([code, color, id]) => ({id, color, code}));

const arr2 = [
  [143, 'FabricB2', 'W5'],
  [189, 'FabricC9', 'W4'],
  [113, 'FabricA3', 'W5'],
].map( ([id, fabric, textile]) => ({id, fabric, textile}));

const query = `
    SELECT arr1.id, arr1.code, arr1.color, arr2.fabric, arr2.textile
    FROM ? AS arr1
    INNER JOIN ? AS arr2 ON arr1.id = arr2.id
`;

var res = alasql(
        query, 
        [arr1, arr2]
    ).map(
        ({id, code, color, fabric, textile}) => [code, color, id, fabric, textile]
    );

console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/alasql/0.5.5/alasql.min.js"></script>

我对您的数据表进行了一些改动,使用解构赋值将它们从数组数组转换为对象数组,然后再转换回来。这种方法的真正强大之处在于,它允许您利用标准 SQL 到 运行 跨多个数据集的各种复杂查询。

  • 使用map创建array2的映射。
  • Filter out array1 根据Map是否有这个array的id。
  • 由于过滤器是一个循环,因此可以修改过滤器内的行

const array1 = [
  ['AB2C', 'Red', 113],
  ['BE4F', 'Green', 164],
  ['AE3G', 'Blue', 143],
];

const array2 = [
  [143, 'FabricB2', 'W5'],
  [189, 'FabricC9', 'W4'],
  [113, 'FabricA3', ' W5'],
];

const array2Map = new Map;
array2.forEach(([row0, ...rest]) => array2Map.set(row0, rest));

const out = array1.filter(row => array2Map.has(row[2]) && row.push(...array2Map.get(row[2])));
console.info(out)