javascript - 尾递归 reduce 函数返回 [..., [Curcular] ]
问题描述
尝试编写一个可以过滤掉任何重复项的 reduce 函数。我知道还有其他方法可以解决这个问题,但我正在尝试练习递归函数。
function addToSet(a, b) {
a.add(b);
return a;
}
let set = new Set;
function reduce([head, ...last], fn, init) {
if (head === undefined) return init;
return fn(fn(init, head), reduce(last, fn, init))
}
const a = reduce([1, 2, 4, 6, 4, 3, 1, 2, 5, 1, 3, 4, 5, 7, 7], addToSet, set)
console.log(a)
// in node this returns // Set { 1, 2, 4, 6, 3, 5, 7, [Circular] }
我读到那个通告意味着对象是自引用的?但我不确定我是否完全理解这在 Set 的上下文中意味着什么。为什么我会遇到这个问题,我该如何解决?非常感谢你们的时间!
解决方案
考虑这一点的一个好方法是只看addToSet
. 它每次都返回传入的集合。现在看看 的返回值reduce
。它返回fn
我们刚刚建立的结果总是返回集合。
因此,当您将结果传递给reduce
第二个参数时fn
,您会将集合传递给第二个参数fn
,第二个参数会将集合添加到集合中并给您一个循环引用。
这个:
return fn(fn(init, head), reduce(last, fn, init))
最终变成:
return fn(init, init)
这并不难解决,因为没有真正的理由要传递两次调用函数。您的基本案例最终将返回集合,因此您只需调用fn
一次并返回reduce
.
function addToSet(a, b) {
a.add(b);
}
let set = new Set;
function reduce([head, ...last], fn, init) {
if (head === undefined) return init
fn(init, head)
return reduce(last, fn, init)
}
const a = reduce([1, 2, 4, 6, 4, 3, 1, 2, 5, 1, 3, 4, 5, 7, 7], addToSet, set)
console.log([...a]) // spreading because sets don't print here
推荐阅读
- c# - WorkflowControlClient - 访问被拒绝
- mongodb - MongoDB 每月运行一次查询
- android - 如何从 res/font 目录链接 android/assets 文件夹中的 css 文件中的字体
- c# - DateTime 从 MMM-yyyy 转换为 dd-MM-yyyy 或 yyyy-MM-dd
- node.js - 关于使用节点后端部署 create-react-app 的建议
- python - Django models.py 年份字段
- laravel - WhereHas on 关系
- java - 未调用自定义 Spring 注释
- swift - 如何解决 CoreML - 验证输入失败 - 形状不在允许的形状的枚举集中
- php - 使用 CodeIgniter-3.1.10 在子文件夹中路由控制器和方法