为何自定义Alasql UDF在分组数据中无法正常工作?
问题:Alasql自定义聚合函数参数为undefined的问题
假设有如下Cat接口:
interface Cat { name: string age: number color: string }
我想要按猫咪颜色分组,对每组的年龄求和。使用Alasql内置的sum函数时,以下代码可正常运行:
const sql = ` SELECT name, sum(age) FROM ? GROUP BY color ` alasql(sql, [cats])
但当我自定义求和函数时,调用mySum时参数xs的值为undefined,代码如下:
import {sum} from 'lodash' alasql.fn.mySum = function(xs) { sum(xs) } const sql = ` SELECT name, mySum(age) FROM ? GROUP BY color ` alasql(sql, [cats])
请问我哪里操作有误?
解决方法
你的问题出在对Alasql自定义聚合函数的API逻辑理解有误,还有代码的小疏漏:
- 聚合函数调用逻辑不匹配:Alasql的聚合函数默认不是一次性接收分组后的整个数组,而是会逐行调用函数,每次传入当前行的字段值,同时需要维护累加状态。你直接把函数写成接收数组的形式,自然会拿到
undefined。 - 函数缺少返回值:原代码里
sum(xs)没有写return,就算参数正确也会返回undefined。
修正有两种可行方式:
方式1:手动实现累加逻辑
按照Alasql默认的聚合函数调用方式,处理逐行累加:
import { sum } from 'lodash' alasql.fn.mySum = function(value, accumulator) { // 第一次调用时初始化累加器 if (accumulator === undefined) { return value; } // 后续调用累加当前值 return accumulator + value; } // SQL调用保持不变 const sql = ` SELECT name, mySum(age) FROM ? GROUP BY color ` alasql(sql, [cats])
方式2:复用lodash的sum,标记为聚合函数
如果想直接接收分组后的数组,需要给函数标记isAggregate: true,告诉Alasql这是一个聚合函数,会把分组后的所有值组成数组传入:
import { sum } from 'lodash' alasql.fn.mySum = { isAggregate: true, fn: function(values) { return sum(values); } } // SQL调用保持不变 const sql = ` SELECT name, mySum(age) FROM ? GROUP BY color ` alasql(sql, [cats])
内容的提问来源于stack exchange,提问作者Sasgorilla
相关产品推荐
相关产品推荐

