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

如何修复Google Apps Script中不同长度数值的数组比较错误

Google Sheets Apps Script 宏数值比较Bug排查

问题概述

我写了一个用于Google Sheets的Apps Script宏,用来对比联赛各队伍的每周得分,通过不同类别分数判断胜负关系,部分类别设置了高分/低分计分逻辑。宏在多数情况下正常,但发现一个Bug:当对比的两个数值量级不同时(比如两位数vs三位数),比较结果会反转,总是给位数短的数值加1,位数相同时逻辑正常。

现有代码

// Get all relevant data from the stat sheet in one go
const statsRange = statSheet.getRange('C8:C234').offset(0, weeks);
const statsData = statsRange.getValues();

// Iterate through teams (assuming 12 teams)
for (let i = 0; i <= 11; i++) {
  for (let j = 0; j <= 11; j++) {
    if (i===11&&j===11) {break}
    if (j===i) {j=j+1;}
    let score = 0;

    // Iterate through stats for each team pair, comparing and calculating score. 
    // Scores are across 19 rows per team in the data set. There are 15 relevant rows. 

    for (let k = 0; k <= 15; k++) { 
      var homeStat = statsData[(19 * i) + k]; 
      var awayStat = statsData[(19 * j) + k];

      // Skip some stats and handle some differently
      if (k === 0 || k === 1 || k === 3 || k === 4) {continue}
      else if (k === 13||k === 14) {
        score += (homeStat < awayStat) ? 1 : (homeStat > awayStat) ? -1 : 0;
      } else {
        score += (homeStat > awayStat) ? 1 : (homeStat < awayStat) ? -1 : 0;
      }
      console.log(i, j, k, homeStat, awayStat, score)
    }
  }
}

示例输入数据集

单元格数值
C198180
C199409
C2000.44
C201114
C202148
C2030.77
C20468
C205542
C20643
C207174
C208107
C20928
C21014
C21155
C2120
C2130
C2147
C215
C216
C217130
C218273
C2190.476
C22065
C22182
C2220.793
C22335
C224360
C22542
C226142
C22787
C22831
C22925
C23052
C2310
C2321
C2337

错误日志示例

| time          | log   | i  | j  | k  | home stat | away stat | score |
|---------------|-------|----|----|----|-----------|-----------|-------|
| 6:59:04 PM    | Info  | 11 | 10 | 2  | [ 0.476 ] | [ 0.44 ]  | 1     |
| 6:59:04 PM    | Info  | 11 | 10 | 5  | [ 0.793 ] | [ 0.77 ]  | 2     |
| 6:59:04 PM    | Info  | 11 | 10 | 6  | [ 35 ]    | [ 68 ]    | 1     |
| 6:59:04 PM    | Info  | 11 | 10 | 7  | [ 360 ]   | [ 542 ]   | 0     |
| 6:59:04 PM    | Info  | 11 | 10 | 8  | [ 42 ]    | [ 43 ]    | -1    |
| 6:59:04 PM    | Info  | 11 | 10 | 9  | [ 142 ]   | [ 174 ]   | -2    |
| 6:59:04 PM    | Info  | 11 | 10 | 10 | [ 87 ]    | [ 107 ]   | -1    | <!-- 此处错误:87 < 107,按逻辑score应减1变为-3,但实际变为-1 -->
| 6:59:04 PM    | Info  | 11 | 10 | 11 | [ 31 ]    | [ 28 ]    | 0     |
| 6:59:04 PM    | Info  | 11 | 10 | 12 | [ 25 ]    | [ 14 ]    | 1     |
| 6:59:04 PM    | Info  | 11 | 10 | 13 | [ 52 ]    | [ 55 ]    | 2     |
| 6:59:04 PM    | Info  | 11 | 10 | 14 | [ 0 ]     | [ 0 ]     | 2     |
| 6:59:04 PM    | Info  | 11 | 10 | 15 | [ 1 ]     | [ 0 ]     | 3     |

问题原因

核心问题是statsData是通过getValues()获取的二维数组,每一个元素都是单元素数组(比如[87]),而非原始数值。直接用数组做大小比较时,JavaScript会将数组转换为字符串(比如[87].toString()得到"87"),然后按字符串字典序比较:

  • "87"和"107"比较时,第一个字符"8"的ASCII码大于"1",所以[87]会被判定为大于[107],导致计分逻辑反转。

修复方案

将获取到的数组元素转换为数值类型,同时处理空值避免出现NaN:

修改后的关键代码片段

for (let k = 0; k <= 15; k++) { 
  // 提取数组中的数值,空值转为0或根据需求处理
  const homeStat = Number(statsData[(19 * i) + k][0]) || 0; 
  const awayStat = Number(statsData[(19 * j) + k][0]) || 0;

  // Skip some stats and handle some differently
  if (k === 0 || k === 1 || k === 3 || k === 4) {continue}
  else if (k === 13||k === 14) {
    score += (homeStat < awayStat) ? 1 : (homeStat > awayStat) ? -1 : 0;
  } else {
    score += (homeStat > awayStat) ? 1 : (homeStat < awayStat) ? -1 : 0;
  }
  console.log(i, j, k, homeStat, awayStat, score)
}

说明

  • 使用Number()将数组中的值转为数值类型,[0]取数组的第一个元素(因为getValues()返回的是每行一个数组)。
  • 用|| 0处理空单元格的情况,避免转换后得到NaN,可根据实际需求调整为空值的处理逻辑(比如视为0或跳过)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 20:04:50