簡體   English   中英

CoffeeScript中的理解對象[dict / hash comprehensions]

[英]Object from comprehension in CoffeeScript [dict/hash comprehensions]

有沒有辦法從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: ''
}
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'

不。 理解只返回CoffeeScript中的數組。 在問題跟蹤器中搜索對象理解 ,您會找到幾個提議,但沒有一個被認為合適。

使用下划線的對象功能 ,您可以這樣做:

form_values = _.object([f.name, f.value] for f in $('input, textarea, select'))

檢查函數庫下划線和此mixin的擴展名_.mash

form_values = ->
  _($('input, textarea, select')).mash f -> [f.name, f.value]

這已經得到了解答,但可能缺乏一些解釋,因為這個成語乍一看是相當神秘的

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 ),它將創建各種字段。

CoffeeScript的創建者建議使用輔助函數將對數組轉換為對象:

form_values = toObject([f.name, f.value] for f in $('input, textarea, select'))

在當前的語言語法中,這可以說是最易讀的方式。 除了缺少語法糖之外,它與Python和其他語言的表現方式非常相似。

輔助函數可以很容易地編寫一次,例如使用@ matyr和@ Sylvain的答案:

// Create a new object from an array of [key, value] pairs.
toObject = (pairs) ->
    new -> @[key] = value for [key, value] in pairs; @

我相信你可以在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映射到name值:

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 = {}綁定 @x || @x = {}如果以前沒有找到,則設置密鑰。

如果你不想使用=>和@,你必須事先定義x:

x = {}
items.forEach (item) => x || x = {}; x[item['key']] = item

{abc:{key:'abc',someVar:1},def:{key:'def',someVar:2}}

不要打敗死馬,但我個人認為這是可讀的,並滿足'一線'的要求,而無需額外的模塊:

form_values = {}; form_values[f.name] = f.value for f in $('input, textarea, select')

不要忘記你仍然可以使用分號來組合Coffeescript中的線條!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM