How to convert an Object {} to an Array [] of key-value pairs in JavaScript
Asked Answered
L

25

471

I want to convert an object like this:

{"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

into an array of key-value pairs like this:

[[1,5],[2,7],[3,0],[4,0]...].

How can I convert an Object to an Array of key-value pairs in JavaScript?

Lycopodium answered 8/8, 2016 at 8:21 Comment(0)
M
714

You can use Object.keys() and map() to do this

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map((key) => [key, obj[key]]);

console.log(result);
Murtagh answered 8/8, 2016 at 8:24 Comment(2)
@blvckasvp Are you using numbers as your keys? If not, when it tries to convert your key to a number it will fail and return NaN instead. If you want to use strings as your keys, change the return from [Number(key), obj[key]] to [key, obj[key]] or use the Object.entries as @Pila suggested in their answerGwenore
for me, it's worked fine. I need to convert the below object let res ={"5":"ManuscriptRequestId","4":"PublishRequestId","9":"AuthorIdentificationId","1":"VisitRequestId","6":"InformationRequestId","3":"RareDocumnetsRequestId","2":"RarePhotoRequestId","7":"BookPurchaseRequestId","8":"StatmentRequestId"} const dataArray = Object.entries(res).map(([key, value]) => ({ key, value }));Unction
A
335

The best way is to do:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.entries(obj);

console.log(result);

Calling entries, as shown here, will return [key, value] pairs, as the caller requested.

Alternatively, you could call Object.values(obj), which would return only values.

Aneroidograph answered 14/5, 2017 at 21:57 Comment(3)
FYI : Object.entries will return [key,value], but the key will be a string, value will differ.Sweepstakes
Using Object.fromEntries() will convert the [key, value] pairs back to an object.Laudable
Object.values() won't have the correct 'keys'...assuming the object's keys are all numbers.Everard
B
82

Object.entries() returns an array whose elements are arrays corresponding to the enumerable property [key, value] pairs found directly upon object. The ordering of the properties is the same as that given by looping over the property values of the object manually.

- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Description

The Object.entries function returns almost the exact output you're asking for, except the keys are strings instead of numbers.

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

console.log(Object.entries(obj));

If you need the keys to be numbers, you could map the result to a new array with a callback function that replaces the key in each pair with a number coerced from it.

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
    const entries = Object.entries(input);
    return entries.map(entry => Object.assign(entry, { 0: +entry[0] }));
}

console.log(toNumericPairs(obj));

I use an arrow function and Object.assign for the map callback in the example above so that I can keep it in one instruction by leveraging the fact that Object.assign returns the object being assigned to, and a single instruction arrow function's return value is the result of the instruction.

This is equivalent to:

entry => {
    entry[0] = +entry[0];
    return entry;
}

As mentioned by @TravisClarke in the comments, the map function could be shortened to:

entry => [ +entry[0], entry[1] ]

However, that would create a new array for each key-value pair, instead of modifying the existing array in place, hence doubling the amount of key-value pair arrays created. While the original entries array is still accessible, it and its entries will not be garbage collected.

Now, even though using our in-place method still uses two arrays that hold the key-value pairs (the input and the output arrays), the total number of arrays only changes by one. The input and output arrays aren't actually filled with arrays, but rather references to arrays and those references take up a negligible amount of space in memory.

  • Modifying each key-value pair in-place results in a negligible amount of memory growth, but requires typing a few more characters.
  • Creating a new array for each key-value pair results in doubling the amount of memory required, but requires typing a few less characters.

You could go one step further and eliminate growth altogether by modifying the entries array in-place instead of mapping it to a new array:

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
  const entries = Object.entries(obj);
  entries.forEach(entry => entry[0] = +entry[0]);
  return entries;
}

console.log(toNumericPairs(obj));
Breeze answered 27/6, 2017 at 22:28 Comment(1)
I like the functional approach. As a shorter alternative: Object.entries(obj).map(e => [+e[0], e[1]]);Teak
C
33

To recap some of these answers now on 2018, where ES6 is the standard.

Starting with the object:

let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
  • Just blindly getting the values on an array, do not care of the keys:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.values(obj));
//[9,8,7,6,5,4,3,2,1,0,5]
  • Simple getting the pairs on an array:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj));
//[["1",9],["2",8],["3",7],["4",6],["5",5],["6",4],["7",3],["8",2],["9",1],["10",0],["12",5]]
  • Same as previous, but with numeric keys on each pair:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).map(([k,v])=>[+k,v]));
//[[1,9],[2,8],[3,7],[4,6],[5,5],[6,4],[7,3],[8,2],[9,1],[10,0],[12,5]]
  • Using the object property as key for a new array (could create sparse arrays):

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).reduce((ini,[k,v])=>(ini[k]=v,ini),[]));
//[undefined,9,8,7,6,5,4,3,2,1,0,undefined,5]

This last method, it could also reorganize the array order depending the value of keys. Sometimes this could be the desired behaviour (sometimes don't). But the advantage now is that the values are indexed on the correct array slot, essential and trivial to do searches on it.

  • Map instead of Array

Finally (not part of the original question, but for completeness), if you need to easy search using the key or the value, but you don't want sparse arrays, no duplicates and no reordering without the need to convert to numeric keys (even can access very complex keys), then array (or object) is not what you need. I will recommend Map instead:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

let r=new Map(Object.entries(obj));
r.get("4"); //6
r.has(8); //true
Crinum answered 12/11, 2018 at 22:38 Comment(3)
The fourth bullet point and onward is completely irrelevant to the question, and the rest of your answer is just summarizing the top three answers here. This answer does not bring anything to the discussion that was not already here or is not completely irrelevant.Breeze
Yes, as the first line state, this is a summary of answers, then update them to use modern ES6 techniques instead of full blow functions. The fourth answer is useful when you are moving JSON arrays from a language that supports associative arrays (e.g. PHP).Crinum
All of the methods provided here have already been provided in their plain form in two of the top three answers, they are not in functions so I dont know what you're on about there. As far as the 4th, as I said it is completely irrelevant to the question asked. It might be relevant to a different question, but not this one. Regardless, JSON is JSON whether it is created using PHP, JavaScript, or Haskell.Breeze
B
30

In Ecmascript 6,

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

var res = Object.entries(obj);

console.log(res);

var obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};
var res = Object.entries(obj);
console.log(res);
Broadminded answered 8/8, 2016 at 12:21 Comment(0)
S
23

Yet another solution if Object.entries won't work for you.

const obj = {
      '1': 29,
      '2': 42
    };
const arr = Array.from(Object.keys(obj), k=>[`${k}`, obj[k]]);
console.log(arr);
Sleety answered 22/8, 2017 at 15:50 Comment(2)
This worked for me. I experienced an issue where importing JSON added indexes that made it impossible to use Angulars ngFor loop. This removed the indexes while preserving the structure.Quiet
@Quiet +1 for using "indexes" instead of "indices". Begone, archaic (ie. arbitrary and meaninglessly deviant) English traditions!Timisoara
B
10

Use Object.keys and Array#map methods.

var obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};
// get all object property names
var res = Object.keys(obj)
  // iterate over them and generate the array
  .map(function(k) {
    // generate the array element 
    return [+k, obj[k]];
  });

console.log(res);
Bocage answered 8/8, 2016 at 8:25 Comment(0)
I
10

Use Object.entries to get each element of Object in key & value format, then map through them like this:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

var res = Object.entries(obj).map(([k, v]) => ([Number(k), v]));

console.log(res);

But, if you are certain that the keys will be in progressive order you can use Object.values and Array#map to do something like this:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}; 

                        // idx is the index, you can use any logic to increment it (starts from 0)
let result = Object.values(obj).map((e, idx) => ([++idx, e]));

console.log(result);
Infundibuliform answered 6/8, 2018 at 7:51 Comment(0)
T
9

You can use Object.values([]), you might need this polyfill if you don't already:

const objectToValuesPolyfill = (object) => {
  return Object.keys(object).map(key => object[key]);
};
Object.values = Object.values || objectToValuesPolyfill;

https://mcmap.net/q/81214/-how-to-use-object-values-on-server-side-in-node-js

Then you can just do:

var object = {1: 'hello', 2: 'world'};
var array = Object.values(object);

Just remember that arrays in js can only use numerical keys so if you used something else in the object then those will become `0,1,2...x``

It can be useful to remove duplicates for example if you have a unique key.

var obj = {};
object[uniqueKey] = '...';
Tournedos answered 26/2, 2020 at 9:21 Comment(0)
K
8

With lodash, in addition to the answer provided above, you can also have the key in the output array.

Without the object keys in the output array

for:

const array = _.values(obj);

If obj is the following:

{ “art”: { id: 1,  title: “aaaa” }, “fiction”: { id: 22,  title: “7777”} }

Then array will be:

[ { id: 1, title: “aaaa” }, { id: 22, title: “7777” } ]

With the object keys in the output array

If you write instead ('genre' is a string that you choose):

const array= _.map(obj, (val, id) => {
    return { ...val, genre: key };
  });

You will get:

[ 
  { id: 1, title: “aaaa” , genre: “art”}, 
  { id: 22, title: “7777”, genre: “fiction” }
]
Kono answered 8/6, 2018 at 8:55 Comment(0)
G
7

If you are using lodash, it could be as simple as this:

var arr = _.values(obj);
Gironde answered 2/3, 2018 at 7:58 Comment(0)
A
5
var obj = { "1": 5, "2": 7, "3": 0, "4": 0, "5": 0, "6": 0, "7": 0, "8": 0, "9": 0, "10": 0, "11": 0, "12": 0 }
let objectKeys = Object.keys(obj);

let answer = objectKeys.map(value => {
    return [value + ':' + obj[value]]
});
Anaerobe answered 6/4, 2021 at 12:7 Comment(0)
M
4
const persons = { 
    john: { age: 23, year:2010},
    jack: { age: 22, year:2011},
    jenny: { age: 21, year:2012}
}
const resultArray = Object.keys(persons).map(index => {
    let person = persons[index];
    return person;
});

//use this for not indexed object to change array
Motet answered 14/4, 2022 at 7:55 Comment(0)
F
3

This is my solution, i have the same issue and its seems like this solution work for me.

yourObj = [].concat(yourObj);
Frum answered 16/10, 2019 at 21:31 Comment(0)
A
3

or you can use Object.assign():

const obj = { 0: 1, 1: 2, 2: 3};
const arr = Object.assign([], obj);
console.log(arr)
// arr is [1, 2, 3]
Alfred answered 18/10, 2022 at 8:38 Comment(0)
U
3

you can use 3 methods convert object into array (reference for anyone not only for this question (3rd on is the most suitable,answer for this question) Object.keys() ,Object.values(),andObject.entries()

examples for 3 methods

use Object.keys()

const text= {
    quote: 'hello world',
    author: 'unknown'
};
const propertyNames = Object.keys(text);

console.log(propertyNames);
result
[ 'quote', 'author' ]

use Object.values()

const propertyValues = Object.values(text);

console.log(propertyValues);

result

[ 'Hello world', 'unknown' ]

use Object.entires()

const propertyValues = Object.entires(text);

console.log(propertyValues);

result

[ [ 'quote', 'Hello world' ], [ 'author', 'unknown' ] ]
Uriiah answered 11/11, 2022 at 16:32 Comment(2)
While this is informative, the question is more specific and can be answered just by the third part. Please consider editing your answer to just answer the question.Germany
yeah, I did mentioned above before answering question anyway I bold it out ( I put 3 answers for reference for those who need to learn about this methods maybe you are pro but I mentioned it for beginners)Uriiah
H
2

Here is a "new" way with es6 using the spread operator in conjunction with Object.entries.

const data = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const dataSpread = Object.entries(data);

// data spread value is now:
[
  [ '1', 5 ],  [ '2', 7 ],
  [ '3', 0 ],  [ '4', 0 ],
  [ '5', 0 ],  [ '6', 0 ],
  [ '7', 0 ],  [ '8', 0 ],
  [ '9', 0 ],  [ '10', 0 ],
  [ '11', 0 ], [ '12', 0 ]
]
Hoseahoseia answered 30/9, 2021 at 17:14 Comment(2)
Using the spread operator here is redundant. There is no need to use it because Object.entries() already returns a 2d array in the expected format.Birkle
Yep, you are right. The outer array isn't needed either, so I've updated the code to get rid of that as well!Hoseahoseia
G
1

Object to Css Array

var cssObj = {'border-radius':'10px'}
var cssArray = [];

// Converting ...
Object.keys(cssObj).map((key) => {
     cssArray[key] = cssObj[key];
});

console.log(cssArray["border-radius"]);

More data:

You can first convert css object to css array, then simply use it :)

Genuflection answered 30/3 at 3:54 Comment(1)
This is not what the question is asking about. This is just misusing arrays.Orthopsychiatry
H
0

Use for in

var obj = { "10":5, "2":7, "3":0, "4":0, "5":0, "6":0, "7":0,
            "8":0, "9":0, "10":0, "11":0, "12":0 };

var objectToArray = function(obj) {
    var _arr = [];

    for (var key in obj) {
        _arr.push([key, obj[key]]);
    }
    return _arr;
}

console.log(objectToArray(obj));
Harlem answered 1/9, 2017 at 19:8 Comment(0)
P
0

Recursive convert object to array

function is_object(mixed_var) {
    if (mixed_var instanceof Array) {
        return false;
    } else {
        return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
    }
}


function objectToArray(obj) {
    var array = [], tempObject;
    for (var key in obj) {

        tempObject = obj[key];

        if (is_object(obj[key])) {
            tempObject = objectToArray(obj[key]);
        }
        array[key] = tempObject;
    }
    return array;
}
Pacer answered 15/11, 2017 at 10:11 Comment(0)
L
0

We can change Number to String type for Key like below:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
  return [String(key), obj[key]];
});
    
console.log(result);
Llovera answered 16/8, 2019 at 4:43 Comment(0)
P
0

Sample Input:

var sampleInput={ name: { firstName: "sangram", midddleName: "shivaji", lastName: "Desai", }, address: { street: "Naradawe Road", line1: "near railway station", line2: "behind annapurna hotel", city: "kankavali", pin: "416602", }, };

Sample Output:

var sampleOutput= [ ["name",[ ["firstName","sangram"], ["midddleName","shivaji"], ["lastName","Desai"] ] ], ["address",[ ["street","Naradawe Road"], ["line1","near railway station"], ["line2","behind annapurna hotel"], ["city","kankavali"], ["pin","416602"] ] ] ]

Solution:

const person = { name: { firstName: "sangram", midddleName: "shivaji", lastName: "Desai", }, address: { street: "Naradawe Road", line1: "near railway station", line2: "behind annapurna hotel", city: "kankavali", pin: "416602", }, };

function convertObjectTwoArray(person) {
    let resultArray = [];
    for (let key in person) {
    if ((typeof person[key]).toString() === "object") {
        resultArray.push([key, convertObjectTwoArray(person[key])]);
    } else {
        resultArray.push([key, person[key]]);
    }
    }
    return resultArray;
}

//find result & print
let resultArray = convertObjectTwoArray(person);
console.log( JSON.stringify(resultArray));

Output:

[ ["name",[ ["firstName","sangram"], ["midddleName","shivaji"], ["lastName","Desai"] ] ], ["address",[ ["street","Naradawe Road"], ["line1","near railway station"], ["line2","behind annapurna hotel"], ["city","kankavali"], ["pin","416602"] ] ] ]

Punch answered 28/3 at 11:43 Comment(0)
R
-1

you can use _.castArray(obj).

example: _.castArray({ 'a': 1 }); // => [{ 'a': 1 }]

Revolting answered 17/9, 2018 at 6:51 Comment(0)
R
-1

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5}

result = Object.entries(obj).map((key,value) => [parseInt(key,10), value])

console.log(result);
Roily answered 1/3, 2023 at 1:7 Comment(1)
This produces the wrong answer. Try running the snippet.Coggins
R
-1

const obj = {
  1: 5,
  2: 7,
  3: 0,
  4: 0,
  5: 0,
  6: 0,
  7: 0,
  8: 0,
  9: 0,
  10: 0,
  11: 0,
  12: 0,
};
const arr = [...new Map(Object.entries(obj))];
console.log(arr);

You can convert your Object to Map first and then use the spread operator to convert the Map into an array , arr is now an array of key-value pairs represented as arrays within the map.

Recitativo answered 10/9, 2023 at 5:31 Comment(1)
You get the exact same result with const arr = Object.entries(obj);. The Map conversion is unnecessary. This has been mentioned several times, and it does not match the expected result.Orthopsychiatry

© 2022 - 2024 — McMap. All rights reserved.