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

Google Sheets开发:按Dojo筛选排除指定名单的最高得分玩家

高效实现Google Sheets的getBest功能方案

纯工作表公式方案(无需脚本,适合新手)

  • 核心逻辑:用QUERY函数单次扫描数据,完成筛选、排序、取最优,比多次嵌套FILTER效率高得多
  • 假设数据结构:
    • Ronin-Games表:A列=玩家名,B列=Dojo,C列=得分,D列=记录时间(无时间列可改用行号)
    • 排除名单表(命名为Exclude):A列=玩家名,B列=对应Dojo
  • 公式示例(假设指定Dojo的单元格为F2):
    =INDEX(QUERY(Ronin-Games!A:D, "SELECT A,C WHERE B = '"&F2&"' AND A NOT IN (SELECT A FROM Exclude WHERE B = '"&F2&"') ORDER BY C DESC, D ASC LIMIT 1", 1))
    
  • 扩展适配:
    • 新增Dojo时,只需在Exclude表中添加对应的“Dojo-玩家”记录即可
    • 无记录时间列时,把排序条件里的D换成ROW(),利用行号判断记录先后(先写入的行号更小)

Apps Script自定义函数方案(性能更优,适合大数据量)

新手用filter性能差的核心原因是多次调用Spreadsheet服务读取数据,改成一次性读入内存处理即可解决。

  • 实现步骤:
    1. 一次性读取Ronin-Games和排除名单的所有数据到内存数组
    2. 把排除名单转换成按Dojo分组的Set集合,实现O(1)时间复杂度的玩家查询
    3. 内存中筛选出目标Dojo且不在排除名单的记录
    4. 按“得分降序、记录先后升序”排序,取第一条结果
  • 简化代码示例:
    function getBest(targetDojo) {
      const ss = SpreadsheetApp.getActiveSpreadsheet();
      const gamesSheet = ss.getSheetByName('Ronin-Games');
      const excludeSheet = ss.getSheetByName('Exclude');
      
      // 一次性读取所有数据,减少服务调用次数
      const gamesData = gamesSheet.getDataRange().getValues();
      const excludeData = excludeSheet.getDataRange().getValues();
      
      // 构建排除名单映射表,快速查询
      const excludeMap = new Map();
      excludeData.forEach(row => {
        const dojo = row[1];
        const player = row[0];
        if (!excludeMap.has(dojo)) excludeMap.set(dojo, new Set());
        excludeMap.get(dojo).add(player);
      });
      
      // 筛选符合条件的记录(跳过表头)
      const filteredRecords = gamesData.slice(1).filter(row => {
        const currentDojo = row[1];
        const currentPlayer = row[0];
        return currentDojo === targetDojo && !excludeMap.get(targetDojo)?.has(currentPlayer);
      });
      
      if (filteredRecords.length === 0) return ['无符合条件的玩家', ''];
      
      // 排序:得分高优先,同分则先达到的在前(用原数据行号判断先后)
      filteredRecords.sort((a, b) => {
        if (b[2] !== a[2]) return b[2] - a[2];
        return gamesData.indexOf(a) - gamesData.indexOf(b);
      });
      
      // 返回玩家名和得分
      return [filteredRecords[0][0], filteredRecords[0][2]];
    }
    
  • 性能优化点:
    • 仅调用2次getDataRange(),避免循环读取单行列
    • 用Map+Set存储排除名单,比遍历数组查询快数倍
    • 所有逻辑在内存中完成,仅返回最终结果

通用扩展建议

  • 数据结构化:不管用公式还是脚本,都把排除名单做成“Dojo-玩家”的二维表,新增Dojo时只需补充记录,无需修改公式或代码
  • 公式避坑:不要用OFFSET、INDIRECT这类易变函数,会触发频繁重计算拖慢速度
  • 脚本进阶:如果数据量超万行,可启用CacheService缓存排除名单和游戏数据,进一步减少重复读取耗时

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:17:39