77

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.

user2864740
  • 60,010
  • 15
  • 145
  • 220
urish
  • 8,943
  • 8
  • 54
  • 75

8 Answers8

121

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.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 2
    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? – technosaurus Aug 09 '14 at 12:50
  • 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. – Bergi Aug 09 '14 at 13:06
  • 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. – technosaurus Aug 10 '14 at 01:03
  • 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 Oct 22 '15 at 16:59
  • 1
    @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`. – Bergi Oct 22 '15 at 20:22
64

just use Object.values

Object.values(inputObj); // => ['foo', [1,2,3], null, 55]
Fareed Alnamrouti
  • 30,771
  • 4
  • 85
  • 76
12

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 }

Mohsen Alyafei
  • 4,765
  • 3
  • 30
  • 42
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."

technosaurus
  • 7,676
  • 1
  • 30
  • 52
  • What's `obj`, why is `ob` global? – Bergi Aug 09 '14 at 11:30
  • Yeah, but it's still a global variable. Use `for (let ob i inputObj)` – Bergi Aug 09 '14 at 11:50
  • @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. – jongo45 Nov 03 '14 at 03:39
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 ]
urish
  • 8,943
  • 8
  • 54
  • 75
  • @Bergi it doesn't work inside the Array Comprehension syntax (at least with Tracuer) – urish Aug 09 '14 at 11:57
  • Yeah, apparently only iterators are supposed to be used within comprehensions. And there's no `Object` iterator - you are supposed to use `Map`s – Bergi Aug 09 '14 at 12:10
  • This fails the jsperf on chrome/firefox http://jsperf.com/objects-to-array/2 I don't know how to fix it though. – technosaurus Aug 09 '14 at 12:31
  • Aren't Array Comprehensions ES7? – bren Dec 22 '15 at 02:38
  • They used to be in ES6, and have been removed since. Per https://github.com/tc39/ecma262, it doesn't seem like they will become a part of the ES7. – urish Dec 22 '15 at 11:53
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]
Despertaweb
  • 1,672
  • 21
  • 29
  • Please augment this code-only answer with some explanation. – Yunnosch Mar 05 '19 at 16:16
  • Sure I could but there's nothing to explain but the [documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values). `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).` – Despertaweb Mar 06 '19 at 08:54
  • 4
    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 – Despertaweb Mar 07 '19 at 11:08
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}`);
KooiInc
  • 119,216
  • 31
  • 141
  • 177
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"]
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103