Google Apps Script数组搜索无匹配:元素为子数组而非字符串
问题:Google Apps Script中getValues()返回子数组导致indexOf匹配失败
我在编写Google Apps Script,用于搜索表格某列数据是否存在匹配项。但使用getValues()获取列数据存入数组后,得到的元素是['数据']形式的子数组而非字符串,导致无法通过indexOf方法找到匹配值。我原以为是带前导0的手机号文本格式问题,但更换其他列后结果仍相同。
代码片段
//Global variables - spreadsheet name, sheet names const This_File = SpreadsheetApp.getActiveSpreadsheet(); const Code_Sheet = This_File.getSheetByName("Button"); const Data_Sheet = This_File.getSheetByName("Current_Members"); function search_ph_num() { //find last row of data var last_row = Data_Sheet.getLastRow() var rng_map = "C2:C"+last_row //var rng_map = "A2:A"+last_row; console.log(rng_map) //testing //SpreadsheetApp.getUi().alert(rng_map); //testing, input dummy data - will be read from email list var dummy_array = ["0412345678", "033999779", "0455667"]; // first number should be found value //set search range to phone number column var this_range = Data_Sheet.getRange(rng_map); var Skt_Number = this_range.getValues(); //search phone numbers for existing data. Assume phone number is unique... pretty valid assumption. for (var i = 0; i <= last_row; i = i + 1){ var isMatched = dummy_array.indexOf(Skt_Number[i]); if (isMatched !== -1) { //SNIP actual code goes here SpreadsheetApp.getUi().alert(Skt_Number[i]); SpreadsheetApp.getUi().alert(i + 2); } //debug if (Skt_Number[i] == "0412345678"){ var insert_dummy = Data_Sheet.getRange("I3"); insert_dummy.setValue(Skt_Number[i]); console.log(Skt_Number[i]) var insert_dummy = Data_Sheet.getRange("J3"); insert_dummy.setValue(dummy_array[0]); console.log(dummy_array[0]) } } }
日志输出
2:08:04 PM 通知 执行开始 2:08:05 PM 信息 C2:C11 2:08:05 PM 信息 [ '0412345678' ] 2:08:05 PM 信息 0412345678 2:08:05 PM 通知 执行完成
可见,[ '0412345678' ]无法与字符串0412345678匹配。请问我哪里操作错误?
操作步骤:将单元格数据存入数组,尝试用indexOf方法搜索数组,预期找到匹配项,但未返回匹配。
解决方法
问题根源
getValues()方法返回的是二维数组,哪怕只选中一列数据。每一行的单元格值都会被包装在子数组里,所以Skt_Number[i]得到的是['手机号']这样的数组,而非单个字符串,用数组和dummy_array里的字符串做indexOf匹配自然失败。- 循环条件
i <= last_row存在越界问题:因为你从第2行开始取数据,getValues()返回的数组长度是last_row - 1,当i等于last_row时,Skt_Number[i]会是undefined。
修复步骤
方案1:扁平化二维数组
用flat()方法直接将二维数组转为一维数组,后续逻辑和普通字符串数组一致:
//Global variables - spreadsheet name, sheet names const This_File = SpreadsheetApp.getActiveSpreadsheet(); const Code_Sheet = This_File.getSheetByName("Button"); const Data_Sheet = This_File.getSheetByName("Current_Members"); function search_ph_num() { var last_row = Data_Sheet.getLastRow() var rng_map = "C2:C"+last_row console.log(rng_map) var dummy_array = ["0412345678", "033999779", "0455667"]; var this_range = Data_Sheet.getRange(rng_map); // 扁平化二维数组为一维字符串数组 var Skt_Number = this_range.getValues().flat(); // 用forEach遍历,避免越界问题 Skt_Number.forEach((number, index) => { var isMatched = dummy_array.indexOf(number); if (isMatched !== -1) { SpreadsheetApp.getUi().alert(number); // 行号为起始行(2)加上数组索引 SpreadsheetApp.getUi().alert(index + 2); } if (number == "0412345678"){ Data_Sheet.getRange("I3").setValue(number); console.log(number) Data_Sheet.getRange("J3").setValue(dummy_array[0]); console.log(dummy_array[0]) } }); }
方案2:直接取子数组元素
如果不想扁平化数组,在循环中直接获取子数组的第一个元素即可:
// 保留原二维数组,循环时取子数组第一个元素 var Skt_Number = this_range.getValues(); for (var i = 0; i < Skt_Number.length; i++){ var phoneNumber = Skt_Number[i][0]; // 提取子数组中的字符串 var isMatched = dummy_array.indexOf(phoneNumber); // 后续逻辑不变 }
额外优化建议
如果数据量较大,用Set存储dummy_array的值可以将查找效率从O(n)提升到O(1):
const dummySet = new Set(dummy_array); // 查找时直接用has方法 if (dummySet.has(phoneNumber)) { // 匹配逻辑 }
内容的提问来源于stack exchange,提问作者Pogla Grate
相关产品推荐
相关产品推荐

