Как создать объект из массива пар ключ-значение?

В 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 для разных способов делать вещи - может быть, вы обнаружите, что вам не нужен диктофон в конце концов.