Сопоставление массива объектов с парами ключ/значение в CoffeeScript
У меня есть массив элементов, к которым я бы хотел применить сопоставление, чтобы преобразовать его в пары значений ключа на одном объекте (чтобы имитировать ассоциативный массив).
Подход в Может ли назначение деструктуризации использоваться для создания проекции в CoffeeScript?, похоже, не работает для меня, так как это приводит к простому массиву вместо ключа/пары значений.
Мой язык выбора - CoffeeScript или JavaScript.
Пример:
[{name: 'a', value: 'b', other: 'c'}, {name: 'd', value: 'e', other: 'f'}]
предполагается преобразовать в:
{
a: 'b',
d: 'e'
}
Предпочтительными являются однослойные.; -)
Ответы
Ответ 1
Чтобы исправить синтаксическую ошибку, вам нужно расширить { @name: @value }
на:
o = {}; o[@name] = @value; o
Затем вы можете объединить объекты с помощью $.extend()
и splat (с пустым объектом, чтобы избежать случайного расширения jQuery):
$.extend {}, $(row).children('input').map(() -> o = {}; o[@name] = @value; o)...
Хотя, более простым вариантом было бы просто использовать 2-лайнер:
result = {}
$(row).children('input').each(() -> result[@name] = @value)
Ответ 2
var arr = [{name: 'a', value: 'b', other: 'c'}, {name: 'd', value: 'e', other: 'f'}];
var obj = arr.reduce(function ( total, current ) {
total[ current.name ] = current.value;
return total;
}, {});
Чистый javascript. Это практически один лайнер, и он выглядит хорошо.
Array.prototype.reduce - ES5, но не сложно подделать. Вот пример прокладки:
Array.prototype.reduce = function ( fun, initVal ) {
var sum = initVal || this[ 0 ],
i = 1, len = this.length;
do {
sum = fun.call( undefined, sum, this[i], i, this );
} while ( ++i < len );
return sum;
};
arr.reduce
- сложная версия arr.map
, которая представляет собой сложную версию arr.forEach
. Вы можете сделать это для того же эффекта:
var obj = {};
arr.forEach(function ( val ) {
obj[ val.name ] = val.value;
});
//and using jQuery.each
var obj = {};
$.each( arr, function ( index, val ) {
obj[ val.name ] = val.value;
});
//latter version in coffeescript:
obj = {}
$.each( arr, (index, val) ->
obj[ val.name ] = val.value
)
Ответ 3
values = {}
values[name] = value for {name, value} in arr
или в javascript:
var values = {}
arr.forEach(function(o){
values[o.name] = o.value
})
Это почти то, с чем компилятор CoffeeScript компилируется.
Ответ 4
Или используя простой ES6:
const old = [
{name: 'a', value: 'b', other: 'c'},
{name: 'd', value: 'e', other: 'f'}
]
const transformed = Object.assign(
{},
...old.map(({name, value}) => ({ [name]: value }))
);
console.log(transformed);
Ответ 5
Используя Array.prototype.reduce():
var arrayOfObjects = [
{name: 'a', value: 'b', other: 'c'},
{name: 'd', value: 'e', other: 'f'}
];
arrayOfObjects.reduce(function(previousValue, currentValue, currentIndex) {
previousValue[currentValue.name] = currentValue.value;
return previousValue;
}, {})
Ответ 6
Посмотрите http://coffeescriptcookbook.com/chapters/arrays/creating-a-dictionary-object-from-an-array
myArray = [{name: 'a', value: 'b', other: 'c'}, {name: 'd', value: 'e', other: 'f'}]
dict = {}
dict[obj['name']] = obj['value'] for obj in myArray when obj['name']?
console.log(JSON.stringify(dict, 0, 2));
Это дает именно то, что вы хотите.