Google Apps Script函数修改外部数组变量,slice方法无法解决
解决Google Apps Script中二维数组浅拷贝导致原数组被修改的问题
问题原因
你使用sourceSValues.slice()实现的是浅拷贝,仅能复制数组的第一层结构。但sourceSValues是二维数组(每个元素对应一行数据的子数组),slice()生成的values数组中,每个子数组仍然是原数组的引用。因此当你对values[f]执行splice操作时,实际修改的是原数组sourceSheetValues里对应的子数组,导致外部变量被篡改。
解决方案
需要对二维数组做深拷贝,确保每个子数组都被独立复制,不再引用原数组的子元素。推荐两种实用方法:
方法1:map + slice(适配Google Sheets返回的数组)
将拷贝数组的代码替换为:
let values = sourceSValues.map(row => row.slice());
map遍历每一行数据,对每个子数组调用slice(),生成独立的行副本,避免修改原数组。
方法2:JSON序列化/反序列化(适用于纯基本类型数组)
如果数组中仅包含字符串、数字等基本类型,也可以用:
let values = JSON.parse(JSON.stringify(sourceSValues));
注意:若数组包含日期对象,该方法会将日期转为字符串,可能不符合需求,因此优先选择方法1。
修改后的完整filterSheet函数
function filterSheet(sheetName, disputeStatus, disputeTypeArr, sourceSValues, removeColumnNumsArr){ let ss = SpreadsheetApp.getActiveSpreadsheet(); let sheet = ss.getSheetByName(sheetName); // 替换为二维数组深拷贝 let values = sourceSValues.map(row => row.slice()); if(removeColumnNumsArr){ removeColumnNumsArr.sort((a, b) => b - a); for(let f = 0; f < values.length; f++){ for(let c = 0; c < removeColumnNumsArr.length ;c++){ values[f].splice(removeColumnNumsArr[c]-1,1); } } } sheet.getRange(2,1,sheet.getLastRow(), sheet.getLastColumn()).clear({contentsOnly: true}); if(values.length !== 0){ sheet.getRange(2, 1, values.length, values[0].length).setValues(values) } };
(注:原代码中使用values[1].length存在空数组报错风险,已改为values[0].length,确保数组非空时能正确获取列数)
验证效果
修改后运行splitDataToTabs,三次Logger.log输出的sourceSheetValues[1].length都会保持为15.0,原数组不会再被修改,两次filterSheet调用都会基于原始数据独立处理。
内容的提问来源于stack exchange,提问作者Connor Stokes
相关产品推荐
相关产品推荐

