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服务读取数据,改成一次性读入内存处理即可解决。
- 实现步骤:
- 一次性读取Ronin-Games和排除名单的所有数据到内存数组
- 把排除名单转换成按Dojo分组的Set集合,实现O(1)时间复杂度的玩家查询
- 内存中筛选出目标Dojo且不在排除名单的记录
- 按“得分降序、记录先后升序”排序,取第一条结果
- 简化代码示例:
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存储排除名单,比遍历数组查询快数倍
- 所有逻辑在内存中完成,仅返回最终结果
- 仅调用2次
通用扩展建议
- 数据结构化:不管用公式还是脚本,都把排除名单做成“Dojo-玩家”的二维表,新增Dojo时只需补充记录,无需修改公式或代码
- 公式避坑:不要用
OFFSET、INDIRECT这类易变函数,会触发频繁重计算拖慢速度 - 脚本进阶:如果数据量超万行,可启用
CacheService缓存排除名单和游戏数据,进一步减少重复读取耗时
内容的提问来源于stack exchange,提问作者Flinx
相关产品推荐
相关产品推荐

