Как преобразовать массив объектов в один объект в JavaScript?


102

У меня есть массив объектов:

[ 
  { key : '11', value : '1100', $$hashKey : '00X' },
  { key : '22', value : '2200', $$hashKey : '018' }
];

Как мне преобразовать его в следующее с помощью JavaScript?

{
  "11": "1000",
  "22": "2200"
}

4
[{key:"11", value:"1100"}, {key:"22", value:"2200"}].reduce(function(m,v){m[v.key] = v.value; return m;}, {})
Дэвид

Ответы:


52

Вероятно, вы ищете что-то вроде этого:

// original
var arr = [ 
  {key : '11', value : '1100', $$hashKey : '00X' },
  {key : '22', value : '2200', $$hashKey : '018' }
];

//convert
var result = {};
for (var i = 0; i < arr.length; i++) {
  result[arr[i].key] = arr[i].value;
}

console.log(result);


2
Ознакомьтесь с ответом FirstOne о современном подходе.
Tibos

134

Крошечное решение ES6 может выглядеть так:

var arr = [{key:"11", value:"1100"},{key:"22", value:"2200"}];
var object = arr.reduce(
  (obj, item) => Object.assign(obj, { [item.key]: item.value }), {});

console.log(object)

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

var object = arr.reduce((obj, item) => ({...obj, [item.key]: item.value}) ,{});

Еще одно решение, которое на 99% быстрее (проверено на jsperf):

var object = arr.reduce((obj, item) => (obj[item.key] = item.value, obj) ,{});

Здесь мы используем оператор запятой, он оценивает все выражения перед запятой и возвращает последнее (после последней запятой). Поэтому мы не копируем objкаждый раз, а присваиваем ему новое свойство.


2
Любил тот! var object = arr.reduce((obj, item) => (obj[item.key] = item.value, obj) ,{});
Sohail

это на одну строку быстрее или обычный цикл?
Jeb50 05

2
@ Jeb50, обычный цикл является самым быстрым, но не намного быстрее оператора запятой. Оператор Object.assign / spread на порядок медленнее: jsperf.com/comma-operator-js
Джош Геллер,

1
Вы забыли выкладывать второй объект({...obj, ...{[item.key]: item.value}}) ,{});
Юля

Спасибо, оборачивать это в объект на самом деле не требуется. Я исправил это.
Шевченко Виктор

59

Мне нравится функциональный подход к решению этой задачи:

var arr = [{ key:"11", value:"1100" }, { key:"22", value:"2200" }];
var result = arr.reduce(function(obj,item){
  obj[item.key] = item.value; 
  return obj;
}, {});

Примечание. Last {}- это начальное objзначение для функции уменьшения. Если вы не укажете начальное значение, arrбудет использован первый элемент (что, вероятно, нежелательно).

https://jsfiddle.net/GreQ/2xa078da/


2
а если ключ динамический?
Стефано Сайта

1
Что ж, вы должны знать, какое свойство данного элемента / объекта следует использовать как ключ, а какое как значение нет? Но если мы предположим, что wfirst prop всегда является ключом, а вторым - значением, мы могли бы использовать функцию обратного вызова, подобную этой: function (obj, item) {var keys = item.keys (); obj [элемент [ключи [0]]] = элемент [ключи [0]]; return obj; }
GreQ

Исправление обратного вызова выше: code var obj = arr.reduce (function (obj, item) {var keys = Object.keys (item); obj [item [keys [0]]] = item [keys [1]]; return obj;}, {});
GreQ

58

Пытаясь исправить этот ответ в разделе Как преобразовать массив объектов в один объект в JavaScript?,

это должно сделать это:

var array = [
    {key:'k1',value:'v1'},
    {key:'k2',value:'v2'},
    {key:'k3',value:'v3'}
];
var mapped = array .map(item => ({ [item.key]: item.value }) );
var newObj = Object.assign({}, ...mapped );
console.log(newObj );


Один лайнер:

var newObj = Object.assign({}, ...(array.map(item => ({ [item.key]: item.value }) )));


12

Чистый способ сделать это с помощью современного JavaScript выглядит следующим образом:

const array = [
  { name: "something", value: "something" },
  { name: "somethingElse", value: "something else" },
];

const newObject = Object.assign({}, ...array.map(item => ({ [item.name]: item.value })));

// >> { something: "something", somethingElse: "something else" }


5

На основании ответов, предложенных многими авторами, я создал тестовый сценарий JsPref. https://jsperf.com/array2object82364

Ниже представлены скриншоты производительности. Меня немного шокирует то, что результат chrome отличается от firefox и edge даже после нескольких запусков.

Край

Fire Fox

Хром


2

Использование Underscore.js :

var myArray = [
  Object { key="11", value="1100", $$hashKey="00X"},
  Object { key="22", value="2200", $$hashKey="018"}
];
var myObj = _.object(_.pluck(myArray, 'key'), _.pluck(myArray, 'value'));

2

Обновление: мир продолжал вращаться. Вместо этого используйте функциональный подход.

Ну вот:

var arr = [{ key: "11", value: "1100" }, { key: "22", value: "2200" }];
var result = {};
for (var i=0, len=arr.length; i < len; i++) {
    result[arr[i].key] = arr[i].value;
}
console.log(result); // {11: "1000", 22: "2200"}

Это удивительно похоже на ответ, который кто-то опубликовал
Александр

1
Потому что вот как вы решаете эту проблему. О наименовании, например: arrayэто зарезервированное ключевое слово, поэтому люди его используют arr. и др.
pstadler 09

0

Вот как динамически принять приведенное выше как строку и интерполировать ее в объект:

var stringObject = '[Object { key="11", value="1100", $$hashKey="00X"}, Object { key="22", value="2200", $$hashKey="018"}]';

function interpolateStringObject(stringObject) {
  var jsObj = {};
  var processedObj = stringObject.split("[Object { ");
  processedObj = processedObj[1].split("},");
  $.each(processedObj, function (i, v) {
      jsObj[v.split("key=")[1].split(",")[0]] = v.split("value=")[1].split(",")[0].replace(/\"/g,'');
  });

  return jsObj
}

var t = interpolateStringObject(stringObject); //t is the object you want

http://jsfiddle.net/3QKmX/1/


0

// original
var arr = [{
    key: '11',
    value: '1100',
    $$hashKey: '00X'
  },
  {
    key: '22',
    value: '2200',
    $$hashKey: '018'
  }
];

// My solution
var obj = {};
for (let i = 0; i < arr.length; i++) {
  obj[arr[i].key] = arr[i].value;
}
console.log(obj)


Хотя это может дать ответ на вопрос, лучше добавить описание того, как этот ответ может помочь решить проблему. Пожалуйста, прочтите Как мне написать хороший ответ, чтобы узнать больше.
Рошана Питигала 04

0

Для этого вы можете использовать функцию lodash mapKeys. Всего одна строчка кода!

Пожалуйста, обратитесь к этому полному образцу кода (скопируйте и вставьте его в repl.it или аналогичный):

import _ from 'lodash';
// or commonjs:
// const _ = require('lodash');

let a = [{ id: 23, title: 'meat' }, { id: 45, title: 'fish' }, { id: 71, title: 'fruit' }]
let b = _.mapKeys(a, 'id');
console.log(b);
// b:
// { '23': { id: 23, title: 'meat' },
//   '45': { id: 45, title: 'fish' },
//   '71': { id: 71, title: 'fruit' } }

-2
        var obj = [
            {id: 1 , name : 'gaju' , class : 'kv'},
            {id: 2 , name : 'tushar' , class : 'Super'}
        ];

        function conv(obj,arg){
        var temp= {};
        var output= {}
        for(key in obj){
        temp[key] = obj[key];
        };

        var i=0;
        for(key in temp){
        var aa = {};
        var value = temp[key][arg];
        aa[value] = temp[i];
        //console.log(aa[value][arg] );
        output[aa[value][arg]]=  aa[value];
        i++;
        }

       console.log(output); 
        }

calling function 

    conv(obj,'class');
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.