web-dev-qa-db-ja.com

CoffeeScriptの理解からのオブジェクト[dict / hashの理解]

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: ''
}
43
aaronstacy

いいえ。内包表記は、CoffeeScriptの配列のみを返します。課題トラッカーで object comprehensions を検索すると、いくつかの提案が見つかりますが、適切なものは見つかりませんでした。

23
Trevor Burnham
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'
26
matyr

機能ライブラリを確認してください アンダースコア および拡張子_.mashこれから mixin

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

アンダースコアのオブジェクト関数 を使用すると、次のことができます。

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

これはすでに回答済みですが、このイディオムはむしろcryptic一見したため、おそらくいくつかの説明が不足しています。

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)を作成することです。

4
Sylvain Leroux

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; @
3
Tobia

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]]})

[{名前: 'a'、値:1}、{名前: 'b'、値:2}、{名前: 'c'、値:3}]

上記は実際にはオブジェクトの理解ではなく、単なる例を示していることに注意してください。

ここで、もう少し構造があり、既知の一意のキーをマップしたいとします。

items = [{key: "abc", someVar: 1}, {key: "def", someVar: 2}]

Pythonでは、次のような簡単なことを行います:{x['key']:x for x in items}

CoffeeScriptでは、注意点はありますが、これらすべてを1行にまとめることができます。

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 = {}
items.forEach (item) => x || x = {}; x[item['key']] = item

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

2
Samuel

死んだ馬を倒すことはありませんが、私は個人的にこれが読みやすく、追加のモジュールを必要とせずに「1行」の要件を満たしていると思います。

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

Coffeescriptの行を組み合わせるためにセミコロンを使用できることを忘れないでください!

0
Jay Janssen