如何在 Google Apps 脚本中的二维数组映射期间 return 一行中的两行

How to return two rows from one during a 2D array map in Google Apps Script

我正在尝试获取从电子表格收到的人口普查数据并将其转换为二维数组以对其进行清理。不幸的是,并非我收到的所有表格的格式都相同,因此我试图让脚本能够使用多种格式。当每人一行时,我可以正常工作,但是当我为每个受抚养人一行而每个员工有多行时,我的脚本不会 return 期望的结果。

工作示例输入:

[
   ["LstNm",    "1st Nm",   "Email",    "EE-SSN",   "Mem-SSN","Relate"]
   ["Smith",    "John",     "a@a.com",  11, 11, "E"]
   ["Wang",     "Jacob",    "a@a.com",  11, 22, "C"]
   ["Da Silva", "Jingle",   "c@c.org",  13, 13, "E"]
   ["Martin",   "Heimer",   "b@b.net",  12, 12, "E"]
   ["Muller",   "Schmidt",  "b@b.net",  12, 22, "S"]
]

问题输入。这是我想要 return 两行的地方,一行用于员工,另一行用于家属。但是在我的代码的当前状态下,它不起作用:

[
   ["LstNm",    "1stNm",    "Email", "EE-SSN", "Mem-SSN", "Relate", "DepLstNm", "Dep1stNm", "Dep-SSN",  "Dep-Relate"]
   ["Smith",    "John",     "a@a.com",  11, 11, "E",      "Wang",   "Jacob",    21, "C"]
   ["Da Silva", "Jingle",   "c@c.org",  13, 13, "E",    ,   ,   ,   ]
   ["Martin",   "Heimer",   "b@b.net",  12, 12, "E",      "Muller", "Schmidt",  22, "S"]
]

两种情况下的预期最终结果都是每人一行,EE-SSN 将员工与受抚养人联系起来:

[
   ["Email",    "1stNm",    "LstNm",    "EE-SSN",   "Mem-SSN",  "Relate"]
   ["a@a.com",  "John",     "Smith",    11, 11, "E"]
   ["a@a.com",  "Jacob",    "Wang",     11, 22, "C"]
   ["c@c.org",  "Jingle",   "Da Silva", 13, 13, "E"]
   ["b@b.net",  "Heimer",   "Martin",   12, 12, "E"]
   ["b@b.net",  "Schmidt",  "Muller",   12, 22, "S"]
]

最后,这是我使用的代码:

function getData(origData, index) {
  var depCheck = index[6]+index[7]+index[8]+index[9]
  if (depCheck < 0) {
    var workData = origData.map(row => ([
      row[index[2]],                      // EMAIL
      row[index[1]],                      // FIRST NAME
      row[index[0]],                      // LAST  NAME
      row[index[3]],                      // SUBSCIBER SSN
      row[index[4]],                      // MEMBER SSN
      row[index[5]],                      // RELATIONSHIP
    ]));
  } else {
    var arr = [[]];
    var workData = origData.flatMap(row => {
      arr.push([
          row[index[2]],                      // EMAIL
          row[index[1]],                      // FIRST NAME
          row[index[0]],                      // LAST  NAME
          row[index[3]],                      // SUBSCIBER SSN
          row[index[4]],                      // MEMBER SSN
          row[index[5]],                      // RELATIONSHIP
        ]);
      if (typeof row[index[6]] !== "undefined" && typeof row[index[8]] !== "undefined" ) {
        arr.push([
          row[index[2]],                      // EMAIL
          row[index[7]],                      // FIRST NAME
          row[index[6]],                      // LAST  NAME
          row[index[3]],                      // SUBSCIBER SSN
          row[index[8]],                      // MEMBER SSN
          row[index[9]],                      // RELATIONSHIP
        ]);
      }
      return arr;
    });
  }
  return workData;
}

function main () {
  const originalSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet3');

  const origData = originalSheet.getRange("A6:F11").getValues();
  console.log(origData);
  var index = [0,1,2,3,4,5,-1,-1,-1,-1];
  var data = getData(origData, index);
  console.log("Single Rows:\n" + data);

  const origData2 = originalSheet.getRange("A13:J16").getValues();
  console.log(origData2);
  var index2 = [0,1,2,3,4,5,6,7,8,9];
  var data2 = getData(origData2, index2);
  console.log("Double Rows:\n" + data2);

  var numRows = data.length;
  var numCols = data[0].length;

  var numRows2 = data2.length;
  var numCols2 = data2[0].length;

  originalSheet.getRange(18,1,numRows,numCols).setValues(data);
  originalSheet.getRange(18,7,numRows2,numCols2).setValues(data2);
}

EDIT 进一步查看代码,我意识到通过在第二张地图中 returning 一个二维数组 returns arr[tempEE, tempDep] 实际上变成了一个3D数组。因此,我将地图切换为 flatMap(请参阅下面的答案),它提供了所需的二维数组。

描述

这是一个修改后的示例,说明如何使用数组函数将 employee/dependant 行分成 2 个单独的行。此示例假设每位员工只有一名受抚养人。

脚本

function testCensus() {
  try {
    let spread = SpreadsheetApp.getActiveSpreadsheet();
    let sheet = spread.getSheetByName("Census");
    let values = sheet.getDataRange().getValues();
    values.forEach( row => Logger.log(row) );
    let header = values.shift();  // remove the header row
    let results = [[].concat(header[2],header[1],header[0],header.slice(3,6))];
    function sort(row) {
      let temp = [].concat(row[2],row[1],row[0],row.slice(3,6));
      results.push(temp);
      if( row[6] !== '' ) {
        temp = [].concat(row[2],row[7],row[6],row[3],row.slice(-2));
        results.push(temp);
      }
    }
    values.forEach( row => sort(row) );
    results.forEach( row => Logger.log(row) );
  }
  catch(err) {
    console.log("Error in testCensus - "+err)
  }
}

Console.log

10:04:57 AM Notice  Execution started
10:04:58 AM Info    [LstNm, 1stNm, Email, EE-SSN, Mem-SSN, Relate, DepLstNm, Dep1stNm, Dep-SSN, Dep-Relate]
10:04:58 AM Info    [Smith, John, a@a.com, 11.0, 11.0, E, Wang, Jacob, 21.0, C]
10:04:58 AM Info    [Da Silva, Jingle, c@c.org, 13.0, 13.0, E, , , , ]
10:04:58 AM Info    [Martin, Heimer, b@b.net, 12.0, 12.0, E, Muller, Schmidt, 22.0, S]

10:04:58 AM Info    [Email, 1stNm, LstNm, EE-SSN, Mem-SSN, Relate]
10:04:58 AM Info    [a@a.com, John, Smith, 11.0, 11.0, E]
10:04:58 AM Info    [a@a.com, Jacob, Wang, 11.0, 21.0, C]
10:04:58 AM Info    [c@c.org, Jingle, Da Silva, 13.0, 13.0, E]
10:04:58 AM Info    [b@b.net, Heimer, Martin, 12.0, 12.0, E]
10:04:58 AM Info    [b@b.net, Schmidt, Muller, 12.0, 22.0, S]
10:04:58 AM Notice  Execution completed

参考

实际上,将第二张地图更改为 flatMap 确实解决了问题,这是我使用的最终代码:

function getData(origData, index) {  
  var depCheck = index[6]+index[7]+index[8]+index[9]
  if (depCheck < 0) {
    var workData = origData.map(row => ([ // The data is simply returned as a 1D arr here
      row[index[2]],                      // EMAIL
      row[index[1]],                      // FIRST NAME
      row[index[0]],                      // LAST  NAME
      row[index[3]],                      // SUBSCIBER SSN
      row[index[4]],                      // MEMBER SSN
      row[index[5]],                      // RELATIONSHIP
    ]));
  } else {
    var arr = [];
    /** Use flatMap here as the returned arr[tempEE, tempDep] is a 2D array being added to an 
      * array workData[arr], flatMap takes the result and flattens it by one level*/
    var workData = origData.flatMap(row => {
      var tempEE = [
          row[index[2]],                      // EMAIL
          row[index[1]],                      // FIRST NAME
          row[index[0]],                      // LAST  NAME
          row[index[3]],                      // SUBSCIBER SSN
          row[index[4]],                      // MEMBER SSN
          row[index[5]],                      // RELATIONSHIP
        ];
      if (typeof row[index[6]] !== "undefined" && typeof row[index[8]] !== "undefined" ) {
        console.log("Dependent - " + row[index[6]])
        var tempDep = [
          row[index[2]],                      // EMAIL
          row[index[7]],                      // FIRST NAME
          row[index[6]],                      // LAST  NAME
          row[index[3]],                      // SUBSCIBER SSN
          row[index[8]],                      // MEMBER SSN
          row[index[9]],                      // RELATIONSHIP
        ];
      }
      var arr = [tempEE, tempDep];
      return arr;
    });
  }
  return workData;
}

function main () {
  const originalSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet3');

  const origData = originalSheet.getRange("A6:F11").getValues();
  console.log(origData);
  var index = [0,1,2,3,4,5,-1,-1,-1,-1];
  var data = getData(origData, index);
  console.log("Single Rows:\n" + data);

  const origData2 = originalSheet.getRange("A13:J16").getValues();
  console.log(origData2);
  var index2 = [0,1,2,3,4,5,6,7,8,9];
  var data2 = getData(origData2, index2);
  console.log("Double Rows:\n" + data2);

  var numRows = data.length;
  var numCols = data[0].length;

  var numRows2 = data2.length;
  var numCols2 = data2[0].length;

  originalSheet.getRange(18,1,numRows,numCols).setValues(data);
  originalSheet.getRange(18,7,numRows2,numCols2).setValues(data2);
}

参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap