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