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