有没有办法从coffeescript的理解中返回一个对象?这样我可以表达这个:
form_values = () ->
ret = {}
ret[f.name] = f.value for f in $('input, textarea, select')
return ret
像这样:
form_values = () -> f.name, f.value for f in $('input, textarea, select')
我想构建一个单个对象(不是一个对象数组)。所以如果标记看起来像这样:
<form name=blah>
<input type=text name=blah1 value=111 />
<textarea name=blah2>222</textarea>
<select name=blah3>
<option value=333a>
<option value=333b>
</select>
</form>
返回的对象将是这样的:
{
blah1: '111',
blah2: '222',
blah3: ''
}
答案 0 :(得分:26)
form_values = new ->
@[f.name] = f.value for f in $ 'input, textarea, select'
this
或
form_values = new class then constructor: ->
@[f.name] = f.value for f in $ 'input, textarea, select'
答案 1 :(得分:22)
不。理解只返回CoffeeScript中的数组。在问题跟踪器中搜索object comprehensions,您会找到几个提案,但没有找到合适的提案。
答案 2 :(得分:7)
从underscore检查功能库mixin和扩展程序_.mash
:
form_values = ->
_($('input, textarea, select')).mash f -> [f.name, f.value]
答案 3 :(得分:6)
使用underscore's object function,您可以执行此操作:
form_values = _.object([f.name, f.value] for f in $('input, textarea, select'))
答案 4 :(得分:4)
这已经得到了回答,但可能缺乏一些解释,因为这个成语一见钟情神秘:
form_values = (new -> @[f.name] = f.value for f in $ 'input, textarea, select'; @)
// ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
// create with |
// a new that |
// empty anonymous |
// object constructor |
// don't forget -/
// to return the
// newly created object
关键的想法是创建一个空对象(new
),其中包含一个匿名构造函数(-> ...
),它将创建各种字段。
答案 5 :(得分:3)
CoffeeScript的创建者suggests using a helper function将对数组转换为对象:
form_values = toObject([f.name, f.value] for f in $('input, textarea, select'))
在当前的语言语法中,这可以说是最易读的方式。除了缺少语法糖之外,它与Python和其他语言的表现方式非常相似。
帮助函数可以很容易地编写一次,例如使用来自@ matyr&s和@ Sylvain的答案的技术:
// Create a new object from an array of [key, value] pairs.
toObject = (pairs) ->
new -> @[key] = value for [key, value] in pairs; @
答案 6 :(得分:2)
我相信你可以在CoffeeScript中没有添加库。
这应该是:
的效果$('input, textarea, select').each (item) => @form_values || @form_values = {}; @form_values[$(item).name] = $(item).value
您可以通过预创建form_values来简化其语法:
form_values = {}
$('input, textarea, select').each (item) -> form_values[$(item).name] = $(item).value
这是一个较长的响应,包含了示例:
举一个非常简单的例子,你想把obj映射到名字值:
items = [ { a: 1 }, { b: 2 }, { c: 3 } ]
items.map((item) -> {name: Object.keys(item)[0], value: item[Object.keys(item)[0]]})
[{name:'a',value:1}, {name:'b',value:2}, {name:'c',value:3}]
请注意,上面并不是对象理解,只是演示了一个例子。
现在假设有更多结构,你只想映射一个已知的唯一键:
items = [{key: "abc", someVar: 1}, {key: "def", someVar: 2}]
在Python中,您可以执行以下简单操作:{x['key']:x for x in items}
在CoffeeScript中,您可以将所有这些内容归结为一行,但需要注意:
items.forEach (item) => @x || @x = {}; @x[item['key']] = item
{abc:{key:'abc',someVar:1}, def:{key:'def',someVar:2}}
在上面的代码中,x先前未在范围内定义,因此使用=>
和@
允许我们将x
与@x || @x = {}
绑定(如果之前未找到),然后设置密钥。
如果您不想使用=&gt;和@你必须事先定义x:
x = {}
items.forEach (item) => x || x = {}; x[item['key']] = item
{abc:{key:'abc',someVar:1}, def:{key:'def',someVar:2}}
答案 7 :(得分:0)
不要打败死马,但我个人认为这是可读的并且满足'一线'要求而无需额外的模块:
form_values = {}; form_values[f.name] = f.value for f in $('input, textarea, select')
不要忘记你仍然可以使用分号来组合Coffeescript中的行!