简体   繁体   English

Google Apps 脚本:当 Arrays 之间存在匹配时,合并 Arrays

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

Background背景

I have two arrays (Array 1 and Array 2).我有两个 arrays(阵列 1 和阵列 2)。 Both of them share an ID type (Column 2 of Array 1 and Column 0 of Array 2).它们都共享一个 ID 类型(数组 1 的第 2 列和数组 2 的第 0 列)。 I want to combine the two arrays vertically only when there is a match in that ID.仅当该 ID 匹配时,我才想垂直组合两个 arrays 。

Starting Arrays:开始 Arrays:

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

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

Desired Ending Array期望的结束数组

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

Methodology方法

It seems to me like the most efficient way to do this would be to:在我看来,最有效的方法是:

  1. Create an empty array.创建一个空数组。
  2. Push Array 1 data to Array 3 if the ID column makes a match with one in Array 2.如果 ID 列与数组 2 中的一个匹配,则将数组 1 的数据推送到数组 3。
  3. Push Array 2 data to Array 3 where the ID column matches with Array 3. We should also only add Columns 1 & 2 of Array 2 so we aren't duplicating the ID Column.将数组 2 的数据推送到数组 3,其中 ID 列与数组 3 匹配。我们还应该只添加数组 2 的第 1 列和第 2 列,这样我们就不会复制 ID 列。

What I've Tried我试过的

For Step 2 I've been trying to push Array 1 to Array 3 with a push and map combo like the below but it's not working properly.对于第 2 步,我一直在尝试将阵列 1 推送到阵列 3,如下所示的推送和 map 组合,但它无法正常工作。 My intention was to take each row of Array 1, run it through every row of Array 2 to check for a match;我的意图是获取 Array 1 的每一行,遍历 Array 2 的每一行以检查是否匹配; if there's a match then push to Array 3.如果有匹配,则推送到阵列 3。

For Step 3 my thought was to take each row of Column 2 of Array 3, run it through each row of Column 0 of Array 2, and when finding a match, concat those to Array 3. I never got past the equation for Step 2 in order to get to this.对于第 3 步,我的想法是获取数组 3 的第 2 列的每一行,遍历数组 2 的第 0 列的每一行,当找到匹配项时,将它们连接到数组 3。我从来没有通过第 2 步的方程为了达到这个目的。

I would REALLY appreciate your help!我将衷心感谢您的帮助!

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] } ) }));

 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)

  • Use map to create a map of array2.使用map创建 array2 的 map。
  • Filter out array1 based on whether Map has this array's id.根据 Map 是否有这个数组的 id 过滤掉数组 1。
  • Since filter is a loop, it is possible to modify the row inside filter由于过滤器是一个循环,因此可以修改过滤器内的行

 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)

I think this should do the trick for you:我认为这应该为您解决问题:

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 沙盒链接

Here's an alternative approach you might be interested in.这是您可能感兴趣的另一种方法。

Now that we have the V8 runtime in Apps Script, you can leverage a 3rd party library like AlaSQL to perform complex SQL queries.现在我们在 Apps Script 中拥有了 V8 运行时,您可以利用像AlaSQL这样的第三方库来执行复杂的 SQL 查询。

Just copy-and-paste the latest version of AlaSQL ( full or minified ) into is own script file in your Apps Script project.只需将最新版本的 AlaSQL( 完整缩小)复制并粘贴到您的 Apps 脚本项目中自己的脚本文件中即可。

Then you can run queries like this:然后你可以运行这样的查询:

 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>

I took a few liberties with your data tables converting them from an array of arrays to an array of objects and back again using destructuring assignments.我对您的数据表进行了一些改动,将它们从 arrays 数组转换为对象数组,然后使用解构赋值再次返回。 The real power of this approach is that it allows you to leverage standard SQL to run all sorts of complex queries across multiple datasets.这种方法的真正威力在于,它允许您利用标准 SQL 跨多个数据集运行各种复杂查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM