CoffeeScript:理解中的虚假逗号由空分隔符连接

时间:2016-09-09 20:04:16

标签: coffeescript list-comprehension

我想要一个方便的功能来连接jQuery父>子选择器字符串。我无法在CS 1.10.0(也在1.7.1中测试)中使用以下内容。我做错了什么?

pcsel = (parent_sel, child_sels...) ->
    ### Uitlity for forming parent > child selector string ###
    childchain = [" > " + child for child in child_sels]
    parent_sel + childchain.join('')

console.log pcsel("foo", "bar") # OK. yields "foo > bar"
console.log pcsel("foo", "bar", "glop") # BAD. yields "foo > bar, > glop"
# Sanity check
console.log "foo" + [" > bat", " > glop"].join('') # OK. yields "foo > bar > glop" 

谢谢!

(我也将此作为CS存储库中的问题发布)

2 个答案:

答案 0 :(得分:1)

循环理解:

expr for e in array

计算到数组。这意味着:

[ expr for e in array ]

实际上是单个元素数组,其第一个(也是唯一的)元素是循环中的数组。更明确地说:

i for i in [1,2,3]

[1,2,3]但是:

[ i for i in [1,2,3] ]

[[1,2,3]]

您的问题是childchain中的pcsel最终会产生额外的嵌套级别,join调用的字符串化会添加意外的逗号。

解决方案是修复pcsel

childchain = (" > " + child for child in child_sels)
# -----------^-------------------------------------^

您需要括号(不是括号)来绕过优先级问题;括号(())和括号([])提供完全不同的功能,因此您需要使用正确的功能。

答案 1 :(得分:0)

据我所知,你所看到的行为是预期的。以下是使用显式数组替换splat时代码的行为:

coffee> ["> " + ['bar']]        # => ['> bar']
coffee> ["> " + ['bar', 'baz']] # =>['> bar,baz']

您还会在节点中看到相同的行为:

> [">" + ['bar']]         // => ['>bar']
> ["> " + ['bar', 'baz']] // => ['> bar,baz']

您可以在使用.join多次调用后,或通过执行以下操作时实现您的目标:

pcsel = (parent_sel, child_sels...) ->    
    child_sels.reduce (memo, sel) ->
        memo + " > #{sel}"
    , parent_sel

console.log pcsel("foo", "bar") # => foo > bar
console.log pcsel("foo", "bar", "glop") # => foo > bar > glop
console.log pcsel("foo", "bar", "glop", "baz") # => foo > bar > glop > baz