如何通过Transducers实现对象转换的函数式组合?代码问题求助
解决Transducers组合对象转换器时的异常问题
嘿,我太懂你这个头疼的问题了!单独跑flip和double都正常,一用compose组合就出{undefined: NaN}这种诡异结果,核心问题出在转换器的输入输出格式不匹配,还有你可能没注意到compose的执行顺序。
问题根源拆解
首先得明确:当你用seq处理对象时,底层会把对象拆解成[key, value]的键值对数组来逐个处理。但你写的两个转换器犯了一个关键错误——它们输出的是单个键值对的对象,而不是下一个转换器期望的[newKey, newValue]数组项:
flip接收[k, v],输出{[v]: k}(一个对象)double接收[k, v],输出{[k]: v+v}(也是一个对象)
再加上compose是从右往左执行的,比如compose(flip, double)实际是先跑double,再把double的结果传给flip。那double输出的是{one: 2}这样的对象,flip试图解构[k, v]就会得到k=undefined、v=undefined,计算v+v自然就是NaN,最终就出现了{undefined: NaN}的结果。
修复方案:保持转换器的数据流一致性
Transducers的核心是传递数据流的单个元素(这里就是[key, value]),所以每个转换器都应该接收[k, v],输出新的[newK, newV]数组,而不是直接返回对象。修改后的代码如下:
// 调整转换器,输出[key, value]数组而非对象 const flip = map(([k, v]) => [v, k]); const double = map(([k, v]) => [k, v + v]); // 现在组合执行完全正常 seq(compose(double, flip), {one: 1, two: 2}); // 执行流程:先double得到[['one',2], ['two',4]] → 再flip得到[[2,'one'], [4,'two']] → seq最终转换为对象:{2: 'one', 4: 'two'} seq(compose(flip, double), {one: 1, two: 2}); // 执行流程:先flip得到[[1,'one'], [2,'two']] → 再double得到[[1,'oneone'], [2,'twotwo']] → 最终对象:{1: 'oneone', 2: 'twotwo'}
为什么单独运行没问题?
因为seq在处理单个转换器时,会自动把转换器输出的对象合并到最终结果里。但当转换器组合时,前一个转换器的输出会直接作为下一个转换器的输入,这时候就必须保证格式统一——都用[key, value]数组,才能让数据流在转换器链中正确传递。
内容的提问来源于stack exchange,提问作者John Abraham
相关产品推荐
相关产品推荐

