2013-04-06 74 views
0

我正在玩coffescript中的一些算法,并以一些意想不到的输出结束。这里是我的代码:递归函数在结果中生成重复项

traverse = (tree, stack) -> 
    stack.push tree.node 
    if not tree.branches 
    stack 
    else 
    traverse branch, stack for branch in tree.branches 

one = { node: 1 } 
two = { node: 2 } 
tree = { node: "+", branches: [one, two] } 

console.log traverse one, [] # => [ 1 ] 
console.log traverse two, [] # => [ 2 ] 
console.log traverse tree, [] # => [ [ '+', 1, 2 ], [ '+', 1, 2 ] ] 

我希望得到,而穿越tree输出是[ '+', 1, 2 ]但这被复制。我在这里错过简单的东西吗?

谢谢。

回答

1

如果函数没有明确的return那么返回值就是最后一个表达式的值。在函数的最后一个表达式是这样的:

if not tree.branches 
    stack 
else 
    traverse branch, stack for branch in tree.branches 

注意两个if S和for s为在CoffeeScript的表达式。

那么if的值是多少,因此函数的值是多少?如果tree.branches在那里,那么你得到stack,否则你得到for的值。一个CoffeeScript的for循环计算到一个数组:

a = (i for i in [0 .. 6]) 
# a is now [0, 1, 2, 3, 4, 5, 6] 

所以,如果tree.branches是存在的,你最终会回到什么transverse返回数组:...的当最终阵列都stack数组的数组的数组。

你只需要一点更加明确的返回值,这样的事情应该做的伎俩:

traverse = (tree, stack) -> 
    stack.push tree.node 
    if tree.branches 
    traverse branch, stack for branch in tree.branches 
    stack # <------------ Now we always return stack 

演示:http://jsfiddle.net/ambiguous/2QJ9e/

+0

啊!你确实是对的。 for循环返回一个数组(外部[]),并且该栈是可变的。所以,即使我们第一次返回堆栈,值是[+ 1],它的值第二次被突变为[+ 1 2]。谢谢。 – j1n3l0 2013-04-06 18:18:48