81

Given a javascript object, how can I convert it to an array in ECMAScript-6 ?

For example, given:

 var inputObj = {a:'foo', b:[1,2,3], c:null, z:55};

The expected output would be:

 ['foo', [1,2,3], null, 55]

The order of the elements in the result is not important to me.

5
  • 1
    I didn't get if you have an answer, for what you are looking here? Commented Aug 9, 2014 at 10:46
  • @Mritunjay A blog post, perhaps.. Commented Aug 9, 2014 at 10:46
  • 1
    No, its fine to do that. It is a decent question and a decent answer. Though I expected it could be added as an answer for a similar question except they don't seem to be es6 specific. Commented Aug 9, 2014 at 10:50
  • 1
    I put a jsperf up here: jsperf.com/objects-to-array/2 Commented Aug 9, 2014 at 12:32
  • use Object.values(inputObj) Commented May 23, 2019 at 11:05

8 Answers 8

126

Use (ES5) Array::map over the keys with an arrow function (for short syntax only, not functionality):

let arr = Object.keys(obj).map((k) => obj[k])

True ES6 style would be to write a generator, and convert that iterable into an array:

function* values(obj) {
    for (let prop of Object.keys(obj)) // own properties, you might use
                                       // for (let prop in obj)
        yield obj[prop];
}
let arr = Array.from(values(obj));

Regrettably, no object iterator has made it into the ES6 natives.

Sign up to request clarification or add additional context in comments.

5 Comments

This method is about 85 times (yes times, not percent) slower than the old school 'for in' method on this test case. Would this change significantly over larger data sets?
How did you execute ES6? What test data did you use, have you tried different sizes? Yes, map is known to be a bit slower than loops.
Firefox has it already enabled, Chrome needs chrome://flags/#enable-javascript-harmony. It runs, but in current implementations it is slow as molasses. I am guessing the reason the object iterators were omitted is that existing JIT compilers can already recognize these patterns in the old school methods.
it's probably not map that is the slow part, the slow part is probably the building of a throwaway array done by Object.keys. If you had a generator func that didn't use Object.keys then I'd expect it would be much closer in speed to for in.
@andy: Taking a look again, there is Reflect.enumerate(obj) that does exactly this. But I have no idea whether it would be faster, especially since it doesn't seem to be implemented anywhere yet. Btw, Object.keys is actually pretty fast in V8, sometimes faster than for in.
67

just use Object.values

Object.values(inputObj); // => ['foo', [1,2,3], null, 55]

2 Comments

Effortless and elegant, but it's esnext feature so you definitely need to look for browser support
@Samiullah everyone now is using babel! Especially if you are using ES6 and cares about browsers compatibility
14

Update August 2020

As a summary, in ES6, there are three (3) variations to convert an Object to an Array as follows:

const MyObjects = {   key1: 'value 1',   key2: 'value 2', };

// Method 1: Converts the keys to Array
// --------------------------------------

Object.keys(MyObjects);
// ['key1', 'key2']

// Method 2 Converts the Values to Array
// --------------------------------------

Object.values(MyObjects);
// ['value 1', 'value 2']

// Method 3 Converts both Values and Keys
// --------------------------------------

Object.entries(MyObjects);
// [ ['key1', 'value 1'], ['key2', 'value 2'] ]

Converting an Array back to an Object can be done as follows:

const array = [  ['one', 1],   ['two', 2], ];

Object.fromEntries(array);

// { one: 1, two: 2 }

Comments

11

I like the old school way:

var i=0, arr=[];
for (var ob in inputObj)
  arr[i++]=ob;

Old school wins the jsperf test by a large margin, if not the upvotes. Sometimes new additions are "mis-features."

3 Comments

What's obj, why is ob global?
Yeah, but it's still a global variable. Use for (let ob i inputObj)
@technosaurus I'm sure that your variable ob in for(var ob in inputObj) is supposed to be a property key. So inside the loop it should be arr[i++]=inputObj[ob];. This makes it 22% slower than the code you have now. But it's still much faster than the others in the linked jsperf.
9

This can be achieved using the Array Comprehension syntax:

[for (key of Object.keys(inputObj)) inputObj[key]]

Usage example:

var inputObj = {a:'foo', b:[1,2,3], c:null, z:55};
var arr = [for (key of Object.keys(inputObj)) inputObj[key]];
console.log(arr);

// prints [ 'foo', [ 1, 2, 3 ], null, 55 ]

5 Comments

@Bergi it doesn't work inside the Array Comprehension syntax (at least with Tracuer)
Yeah, apparently only iterators are supposed to be used within comprehensions. And there's no Object iterator - you are supposed to use Maps
This fails the jsperf on chrome/firefox jsperf.com/objects-to-array/2 I don't know how to fix it though.
Aren't Array Comprehensions ES7?
They used to be in ES6, and have been removed since. Per github.com/tc39/ecma262, it doesn't seem like they will become a part of the ES7.
9

ES7 way:

let obj = { a: "foo", b: "bar", c: 1, d: [1, 2, 3, 4] }

Object.values(obj)

// output --> ['foo', 'bar', 1, [1, 2, 3, 4]

3 Comments

Please augment this code-only answer with some explanation.
Sure I could but there's nothing to explain but the documentation. The Object.values() method returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
Dude this is a basic information of the method, this is not the purporse of the topic. It is crystal clear with the example. @Yunnosch
5

Array.map equivalent of @Bergi's arrow function (see MDN for more about Array.map).

Edit 2020: converted to snippet and added an alternative

const obj = {
    a: 'foo',
    b: [1, 2, 3],
    c: null,
    z: 55
  },
  nwArr = Object.keys(obj).map(k => obj[k]),
  // Alternative
  nwArr2 = Object.fromEntries(Object.entries(obj));
  nwArr.a = "bar";
  nwArr2.a = "foobar"
  console.log(`obj.a: ${obj.a}, nwArr.a: ${nwArr.a}, nwArr2.a: ${nwArr2.a}`);

1 Comment

Even more compact version of this Object.keys(obj).map(k => obj[k])
0
const address = {
        street: "bew1111",
        city: "err111",
        country: "ind11"
    };
    const address2 = {
        street: "bewscxsd",
        city: "errdc",
        country: "indcdsc"
    };

we have two objects here and I am going to use 2 methods for assign both objects into Array

  1. Object.entries()

  2. Object.keys()

1st one starts here-----

var firstar = Object.entries(address);

here I assigned address into firstar and when you will run this you will get output like this

(3) [Array(2), Array(2), Array(2)]

2nd one starts here

var secstar = Object.keys(address2);

here I assigned address2 into secstar and when you will run this you will get output like this

 (3) ["street", "city", "country"]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.