45

Given a JavaScript object, how can I convert it into an array of objects (each with key, value)?

Example:

var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe@gmail.com' }

resulting like:

[
  { key: 'firstName', value: 'John' },
  { key: 'lastName', value: 'Doe' },
  { key: 'email', value: 'john.doe@gmail.com' }
]
Rob Brander
  • 3,702
  • 1
  • 20
  • 33

11 Answers11

109

var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe@gmail.com' }
var output = Object.entries(data).map(([key, value]) => ({key,value}));

console.log(output);

Inspired By this post

atiq1589
  • 2,227
  • 1
  • 16
  • 24
  • Great answer. It's worth noting that the REVERSE can also be done, i.e. key-value to objects: Object.fromEntries(data.map(({key,value})=>([key, value]))); – Vijay Jagdale Jan 10 '22 at 21:34
24

Using map function

var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe@gmail.com' };

var result = Object.keys(data).map(key => ({ key, value: data[key] }));

console.log(result);
    
isvforall
  • 8,768
  • 6
  • 35
  • 50
10

You can just iterate over the object's properties and create a new object for each of them.

var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe@gmail.com' };
var result = [];

for(var key in data)
{
    if(data.hasOwnProperty(key))
    {
        result.push({
            key: key,
            value: data[key]
        });
    }
}
Alexander Popov
  • 836
  • 5
  • 18
  • up for `hasOwnProperty` – Roko C. Buljan Apr 04 '16 at 19:51
  • up for `hasOwnProperty` but down for not doing it in a functional way, like @isvforall – Emil Oberg Apr 04 '16 at 19:55
  • @EmilOberg not doing it in a `ES6` way does not mean this is a not reliable (even great and far more readable) answer. A downvote seems odd. – Roko C. Buljan Apr 04 '16 at 20:01
  • @roko-c-buljan, there's nothing ES6 about it. `Object.keys` and `Array.map` is all good old EcmaScript 5.1. (Yes the arrow function @isvforall used is ES6 but not really an interesting part of the answer, e.g see the answer by @rob-brander) – Emil Oberg Apr 04 '16 at 20:08
  • @EmilOberg—"*there is nothing ES6 about it*" — except for the ES6 bits (arrow function, shorthand properties). :-/ – RobG Apr 26 '17 at 08:39
7

The previous answer lead me to think there is a better way...

Object.keys(data).map(function(key) {
  return { key, value: data[key] };
});

or in ES6 using arrow functions:

Object.keys(data).map((key) => ({ key, value: data[key] }));
Rob Brander
  • 3,702
  • 1
  • 20
  • 33
5

Just make your life easier and use es6 syntax with a map

    var output = Object.keys(data).map(key => {
      return {
        key: key,
        value: data[key]
      };
    })
Rob Wilkinson
  • 296
  • 1
  • 7
3
var result = [];
for(var k in data) result.push({key:k,value:data[k]});
Gene R
  • 3,684
  • 2
  • 17
  • 27
1

Or go wild and make the key and value keys customizable:

module.exports = function objectToKeyValueArray(obj, keyName = 'key', valueName = 'value') {
    return Object
        .keys(obj)
        .filter(key => Object.hasOwnProperty.call(obj, key))
        .map(key => {
            const keyValue = {};
            keyValue[keyName] = key;
            keyValue[valueName] = obj[key];

            return keyValue;
        });
};
mandarin
  • 1,316
  • 1
  • 15
  • 27
1

An alternative method for doing this that works on multi level objects and does not use recursion.

var output = []

    var o = {
      x:0,
      y:1,
      z:{
        x0:{
          x1:4,
          y1:5,
          z1:6
        },
        y0:2,
        z0:[0,1,2],
      }
    }

    var  defer = [ [ o ,[ '_root_' ] ] ]
    var _defer = []


    while(defer.length){

    var current = defer.pop()

    var root    = current[1]
        current = current[0]


      for(var key in current ){

        var path = root.slice()
            path.push(key)

        switch( current[key].toString() ){
        case '[object Object]':
          _defer.push( [ current[key] , path ] )
        break;;
        default:
         output.push({
          path  : path ,
          value : current[key]
         })
        break;;
        }
      }

      if(!defer.length)
          defer = _defer.splice(0,_defer.length)
    }

[
{ path: [ '_root_', 'x' ], value: 0 },
{ path: [ '_root_', 'y' ], value: 1 },
{ path: [ '_root_', 'z', 'y0' ], value: 2 },
{ path: [ '_root_', 'z', 'z0' ], value: [ 0, 1, 2 ] },
{ path: [ '_root_', 'z', 'x0', 'x1' ], value: 4 },
{ path: [ '_root_', 'z', 'x0', 'y1' ], value: 5 },
{ path: [ '_root_', 'z', 'x0', 'z1' ], value: 6 }
]
Tegra Detra
  • 24,551
  • 17
  • 53
  • 78
0

const array = [
    { key: "key1", value: "value1" },
    { key: "key2", value: "value2" },
];

const obj = Object.fromEntries(array.map(item => [item.key, item.value]));

console.log(obj);
-2

I would say to use npm package flat. works amazing for nested objects and arrays.

var flatten = require('flat')

flatten({
    key1: {
        keyA: 'valueI'
    },
    key2: {
        keyB: 'valueII'
    },
    key3: { a: { b: { c: 2 } } }
})

// {
//   'key1.keyA': 'valueI',
//   'key2.keyB': 'valueII',
//   'key3.a.b.c': 2
// }
Kathan Shah
  • 1,655
  • 17
  • 25
-2
const array = [
    { key: "key1", value: "value1" },
    { key: "key2", value: "value2" },
];

const obj = Object.fromEntries(array.map(item => [item.key, item.value]));

console.log(obj);
  • 1
    While this code may resolve the OP's issue, it is best to include an explanation as to how your code addresses the OP's issue. In this way, future visitors can learn from your post, and apply it to their own code. SO is not a coding service, but a resource for knowledge. Also, high quality, complete answers are more likely to be upvoted. These features, along with the requirement that all posts are self-contained, are some of the strengths of SO as a platform, that differentiates it from forums. You can edit to add additional info &/or to supplement your explanations with source documentation. – ysf Jun 27 '20 at 23:01