You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用findIndex时触发TypeError: Cannot read properties of undefined的排查

问题排查:TypeError: Cannot read properties of undefined (reading 'includes')

错误场景

错误触发于以下代码行:

var nameIndex = dataFlatArr.findIndex(s => s.includes(lastName) && s.includes(firstName));

使用Sheets.Spreadsheets.Values.get批量加载数据时出现该错误,但调用普通getValues()时脚本正常运行。脚本预期找到同时包含firstName: 'Steve'和lastName: 'Jobs'的单元格(预期结果为Jobs, Steve Apple,对应列索引1)。

相关代码

主执行脚本

var firstName = 'Steve';
var lastName = 'Jobs';
var dataArr =  getValues_({ spreadsheetId: fileID, sheetName: sht.getName(), start: 1, maxRow: lastRow, limit: 100000 });
var columnsArr = [1,2,3,4];

for(var i in columnsArr){ 
  if(foundColTrigger == 'No'){
    var dataFlatArr = dataArr.map(r => r[columnsArr[i]-1]);
    //Logger.log(dataFlatArr);
    var nameIndex = dataFlatArr.findIndex(s => s.includes(lastName) && s.includes(firstName));
    Logger.log(nameIndex);
    if(nameIndex != -1){
      foundColTrigger = 'Yes';
      indexColumn = columnsArr[i]-1;
      var fullDisplayName = dataArr[nameIndex][columnsArr[i]-1];
      Logger.log(fullDisplayName)
    }          
  }
}

批量数据加载函数

//getValues in batches of 100K rows
function getValues_({ spreadsheetId, sheetName, start = 1, maxRow, limit = 100000 }) {
  return [...Array(Math.ceil(maxRow / limit))].flatMap((_) => {
    const last = start - 1 + limit;
    const range = `'${sheetName}'!A${start}:${last > maxRow ? maxRow : last}`;
    const temp = Sheets.Spreadsheets.Values.get(spreadsheetId, range).values;
    start += limit;
    return temp;
  });
}

表格数据示例

Participants AParticipants BParticipants CParticipants D
Jackson, MichaelWozniak, SteveJames, LebronBonds, Barry
Blige, Mary JGates, BillJordan, Michael JMcGwire, Mark
Carey, MariahCook, TimCurry, StephenSosa, Sammy
Jackson, JanetJobs, MarkDurant, KevinJudge, Aaron
Houston, WhitneyJobs, Steve AppleAbdul-Jabbar, KareemMaris, Roger
Mercury, FreddieMusk, ElonRussell, BillRuth, Babe

问题原因

Sheets.Spreadsheets.Values.get返回的values数组与普通getValues()存在核心差异:当表格中存在空单元格时,API会直接跳过该单元格,不会在数组中生成对应元素;而getValues()会用空字符串""填充所有空单元格位置,保证每行数组长度一致。

这种差异导致当你通过r[columnsArr[i]-1]提取列值时,若对应位置的单元格为空,会得到undefined,调用includes()方法自然触发TypeError。


解决方案

  • 方案1:修复批量加载函数,补全空单元格
    修改getValues_函数,确保每行数组长度与表格列数一致,用空字符串填充缺失的单元格:
//getValues in batches of 100K rows, 补全空单元格
function getValues_({ spreadsheetId, sheetName, start = 1, maxRow, limit = 100000 }) {
  // 获取表格总列数,确保每行长度统一
  const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
  const columnCount = sheet.getLastColumn();
  
  return [...Array(Math.ceil(maxRow / limit))].flatMap((_) => {
    const last = start - 1 + limit;
    const range = `'${sheetName}'!A${start}:${last > maxRow ? maxRow : last}`;
    const temp = Sheets.Spreadsheets.Values.get(spreadsheetId, range).values || [];
    // 补全每行的空单元格
    const filledRows = temp.map(row => {
      while(row.length < columnCount) {
        row.push("");
      }
      return row;
    });
    start += limit;
    return filledRows;
  });
}

处理后dataArr结构与getValues()返回结果一致,不会出现undefined,后续includes()调用可正常执行。

  • 方案2:在查找逻辑中增加空值判断
    若不想修改加载函数,可在findIndex的回调中先判断目标值是否存在:
var nameIndex = dataFlatArr.findIndex(s => s && s.includes(lastName) && s.includes(firstName));

该方案更轻量,当单元格为空时会自动跳过,避免触发错误。

  • 速度优化建议
    • 方案1中获取列数的操作仅执行一次,不会影响批量加载的速度优势。
    • 若表格列数固定(如示例中的4列),可直接将columnCount设为固定值,省去调用getLastColumn()的开销。

内容的提问来源于stack exchange,提问作者DanCue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:50:15