Подтвердить что ты не робот

Объект от понимания в CoffeeScript [dict/hash assrehensions]

Есть ли способ вернуть объект из понимания в 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: ''
}
4b9b3361

Ответ 1

Неа. Понятия только возвращают массивы в CoffeeScript. Найдите отслеживание проблем для объектов понимания, и вы найдете несколько предложений, но ни один из них не был найден подходящим.

Ответ 2

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'

Ответ 3

Проверьте функциональную библиотеку underscore и расширение _.mash из этого Mixin:

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

Ответ 5

Это уже ответили, но, вероятно, не было никаких объяснений, поскольку эта идиома довольно загадочна с первого взгляда:

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) с анонимным конструктором (-> ...), который будет создавать различные поля.

Ответ 6

Я считаю, что вы можете сделать это без добавления библиотек прямо в 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}]

Обратите внимание, что приведенное выше не является постижением Object, просто демонстрируя пример.

Теперь скажем, что есть немного больше структуры, и вы просто хотите отобразить известный уникальный ключ:

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

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

Ответ 7

Создатель 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; @