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 ]が、これは複製されます。ここで簡単なことを見逃しましたか?

ありがとう。

4

1 に答える 1

1

関数に明示的なものがない場合return、戻り値は最後の式の値です。関数の最後の式は次のとおりです。

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

ifs とfors はどちらも CoffeeScript の式であることに注意してください。

では、そのif値と関数の値は何でしょうか? がある場合tree.branchesは を取得stackし、そうでない場合は の値を取得しますfor。CoffeeScriptforループは配列に評価されます。

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

したがって、tree.branchesそこにある場合は、返されるものの配列をtransverse返すことになります: 配列の配列の配列 ... 最終的な配列は allstackです。

戻り値についてもう少し明示する必要があるだけです。次のような方法でうまくいくはずです。

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/

于 2013-04-06T18:04:11.523 に答える