javascript - 尾递归reduce函数返回[..., [Circular] ]

标签 javascript node.js function recursion circular-reference

尝试编写一个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] }

我读到循环意味着该对象是自引用的?但我不确定我是否完全理解这在集合的上下文中意味着什么。为什么我会遇到这个问题,我该如何解决? 非常感谢你们抽出时间!

最佳答案

考虑这个问题的一个好方法是只查看 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
  

关于javascript - 尾递归reduce函数返回[..., [Circular] ],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51904703/

相关文章:

algorithm - Skolem 序列生成器算法

javascript - 如何将循环 JSON 对象字符串化并将其保存到文件中?

javascript - 用新数据替换 observableArray

javascript - 通过对象数组和数组来 react 映射

javascript - Redux - 应用程序状态以 reducer 的名称作为键

javascript - 提交表单时转到新的 html 页面

javascript - 我如何将 gulp 与磁带一起使用?

php - MySQL:在带有@rownum 的php 函数中左联接?

mysql - 如何使用 Node.js Lambda 函数与 RDS MySQL 实例交互?

C - 将二维数组上的指针传递给函数