繁体   English   中英

如何使用 Google Scripts & Google Sheets 执行 Cartesian Join?

[英]How to perform Cartesian Join with Google Scripts & Google Sheets?

我找到了基本的 2 列笛卡尔连接的代码,但我的情况略有不同。

有 3 个变量/列:颜色、颜色 ID 和项目。

我想要颜色和项目的每种组合。 我想要第三个变量,颜色 ID 与颜色变量一起附加到臀部。

这是一个示例电子表格。 AC 列是输入数据,EG 列是所需的 output(顺序不重要。)

https://docs.google.com/spreadsheets/d/1LgWttzY317T3N66Wk2JbDq8nETSGl1HCxY8u8i0jhl4/edit#gid=0

我相信你的目标如下。

  • 您想使用 Google Apps 脚本实现以下转换。

    •  Blue 74 Shirt Red 48 Pants Green 55 Shoes Hat Socks Backpack
    •  Blue 74 Shirt Blue 74 Pants Blue 74 Shoes Blue 74 Hat Blue 74 Socks Blue 74 Backpack Red 48 Shirt Red 48 Pants Red 48 Shoes Red 48 Hat Red 48 Socks Red 48 Backpack Green 55 Shirt Green 55 Pants Green 55 Shoes Green 55 Hat Green 55 Socks Green 55 Backpack
  • 在您的示例电子表格中, Green, 55具有相同的值,即Backpack 但是从您的示例模式中,我认为您可能想要 avove 转换。

如果我的理解是正确的,我想提出以下流程。

  1. 从“A”到“C”列中检索值。
  2. 转置检索到的值。
  3. 创建用于放入电子表格的数组。
  4. 把价值观。

当上述流程反映到脚本时,它变成如下。

示例脚本:

请将以下脚本复制并粘贴到电子表格的脚本编辑器中,然后运行myFunction 这样,结果值将被放入“I2:K”列。

function myFunction() {
  const sheetName = "Sheet1";  // Please set the sheet name.

  // 1. Retrieve the values from the columns "A" to "C".
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  const values = sheet.getRange("A2:C" + sheet.getLastRow()).getValues();

  // 2. Transpose the retrieved values.
  const [color, id, item] = values[0].map((_, i) => values.map(r => r[i]).filter(String));

  // 3. Create the array for putting to Spreadsheet.
  const res = color.flatMap((e, i) => item.map(g => [e, id[i], g]));

  // 4. Put the values.
  sheet.getRange(2, 9, res.length, res[0].length).setValues(res);
}

结果:

当为您的示例电子表格运行上述脚本时,将获得以下结果。

在此处输入图像描述

参考:

作为一个简单的谷歌表格公式,

  • 用分隔符连接AB
  • 将上述结果与TRANSPOSE d C和分隔符连接起来。 这将创建一个笛卡尔积矩阵
  • FLATTEN上述结果展平
  • 按分隔符SPLIT以再次取回 3 列。

=ARRAYFORMULA(SPLIT(FLATTEN(A2:A4&"💎"&B2:B4&"💎"&TRANSPOSE(C2:C7)),"💎"))
  • 如果您想要一个开放式范围,请使用INDEX/COUNTA

Tanaike 的回答很好,请接受他的回答,但这是以防万一您想在工作表中将其用作自定义 function (公式):

function cartesian(startCol) {
  const sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const vals = sh.getRange(2, startCol, sh.getLastRow(),3).getValues();
  const input  = [...Array(3)].map((_, i) => 
                 vals.map(r => r[i]).
                 filter(e=>e!=''));
  const res = input[0].map((color, i) => 
              input[2].
              map(item => [color, input[1][i], item])).
              flat();
  return res;
}

然后使用=cartesian(startCol)在您的情况下startCol1作为输入数据的第一列:

在此处输入图像描述

根据TheMaster的回答,只有“增长”的表格大小:

=ARRAYFORMULA(SPLIT(FLATTEN(offset(A2,0,0,counta(A2:A),1)&"💎"&offset(B2,0,0,counta(B2:B),1)&"💎"&TRANSPOSE(offset(C2,0,0,counta(C2:C),1))),"💎"))

我已将公式添加到问题中的示例电子表格中。

暂无
暂无

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

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