Как создать объект из массива пар ключ-значение?
В Python можно передать конструктору dict
1 последовательность пар ключ-значение:
>>> dict([['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']])
{'age': 42, 'name': 'Bob', 'breakfast': 'eggs'}
Я не могу придумать никакого способа сделать это в JavaScript, кроме определения моей собственной функции для этой цели:
function pairs_to_object(pairs) {
var ret = {};
pairs.forEach(function (p) { ret[p[0]] = p[1]; });
return ret;
}
Но я JS noob... Есть ли что-то встроенное для такого рода преобразование между объектами?
1 Для целей этого вопроса я рассматриваю Python dicts как Python-аналог объектов JS, хотя, конечно, сходство ограничивается только тем фактом, что они являются коллекциями ключевых значений.
Ответы
Ответ 1
На момент написания (2013) объекты/словари/ассоциативные массивы JavaScript изначально не имели такого конструктора.
Как вы сами сказали, вы, конечно, можете создать свою собственную функцию, используя, например, функциональный подход, используя функцию reduce
, как объяснено в одном из других ответов. Конечно же, подойдет классический цикл for или более новый цикл forEach. Но нет ничего встроенного.
Изменить: это 2019 год, и теперь у нас есть Object.fromEntries, который даст вам то, что вам нужно.
Ответ 2
Object.fromEntries
выполняет свою работу. Он был добавлен в язык с помощью EcmaScript2019.
Если у вас нет поддержки этой функции, вы можете определить ее самостоятельно с помощью следующего кода ES2015:
Object.fromEntries = arr => Object.assign({}, ...Array.from(arr, ([k, v]) => ({[k]: v}) ));
Приятно то, что этот метод работает противоположно Object.entries
(ES2017), поэтому теперь вы можете переходить от одного объекта к другому к другому и представлять его в массиве:
const arr = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
const obj = Object.fromEntries(arr);
console.log(obj);
// ... and back:
const arr2 = Object.entries(obj);
console.log(arr2); // copy of the original array (omitting duplicate keys)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ответ 3
Вы можете использовать функцию уменьшения
x = [[1,2],[3,4],[5,6]];
o = x.reduce(function(prev,curr){prev[curr[0]]=curr[1];return prev;},{})
o теперь эквивалентно {1:2, 3:4, 5:6}
Если ваш входной массив разрежен, вам нужно добавить тест if(curr!=undefined)
при назначении, но обязательно верните "prev".
Если ваш кортеж является чем-то более сложным, чем простой [ключ, значение], вы можете просто изменить способ присвоения "prev". Например: prev["key-"+curr[0].toString()]=curr[1]*2;
Ответ 4
Функция Lodash fromPairs сделает это:
const _ = require('lodash')
const kvPairs = [['a', 1], ['b', 2]]
_.fromPairs(kvPairs)
// => { a: 1, b: 2 }
Ответ 5
Javascript не имеет встроенной функции для преобразования массива в объект так, как вы описали. Но это потому, что в этом нет необходимости. Вы уже включили в вопрос примерное решение, где вы сами определяете функцию, но это действительно не нужно. Пока вы можете быть уверены, что входной массив верен, вы даже можете сделать преобразование с помощью простого цикла, например:
var input = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
var output = {};
for(i in input) output[input[i][0]] = input[i][1];
Это самый простой код, который можно себе представить.
Конечно, (как указывает мамапитуфо), вообще-то плохая идея на самом деле использовать for..in для итерации по массиву, потому что это также вернет неиндексы в качестве значений i. Тем не менее, дело в том, что этот вид операции слишком прост и слишком редко необходим, чтобы оправдать наличие собственной функции.
Python dict - это структура, которая не нужна в javascript, потому что у двух языков есть разные подходы к набору текста и для разработки в целом, и поэтому то, что полезно для одного, не полезно для другого. Хотя вы могли бы работать над использованием тех же методов и структур, которые вы использовали в python, может быть, лучше подумать о том, как использовать javascript для разных способов делать вещи - может быть, вы обнаружите, что вам не нужен диктофон в конце концов.