Christian
Christian

Reputation: 7429

Fastest way to turn an Object into an Array

I've seen a lot of ways to turn a Javascript object into an array. One thing that I am using is this:

shims.values = function (obj) {
    var keys = Object.keys(obj);
    var length = keys.length;
    var values = new Array(length);
    for (var i = 0; i < length; i++) {
        values[i] = obj[keys[i]];
    }
    return values;
};

I know there's nothing like Object.keys (Object.values would be awesome).

Now if I have an Object with thousands of values which I want to turn into an Array, the function above get's a bit slow.

E.g. Turn this:

{
    1: {a:"a"},
    1: {b:"b"},
    ....
    1000000: {c:"c"},
}

into this:

  [{a:"a"},{b:"b"},...,{c:"c"}]

Is there a better (faster) way?

Upvotes: 1

Views: 1094

Answers (4)

cocco
cocco

Reputation: 16706

This is prolly the shortest & fastest way using pure old js.

and it's compatible with all browsers.

var a=[],b;
for(b in obj){
 a.push(obj[b]);
}

DEMO

http://jsfiddle.net/B72Sa/

or like @GJK mentioned with newer js versions

Array.prototype.slice.call

if its a sequential numeric value.

Note: it depends alot on the keys of the object... you can't sort an object.

EDIT - PERFORMANCE

http://jsperf.com/for-vs-array-proto

EDIT2

hasOwnProperty is not needed anymore as @Christian is using Object.keys(obj) which is part of a newer version of javascript... and in that case prototypes can be defined without beeing enumerable.

example:

Object.defineProperty(obj.prototype,'myProto',{value:function(){
 return this; 
},writable:false,enumerable:false});

EDIT3

there is nothing faster than plain old javascript.

Array.prototype.slice.call

means you execute slice than call... so 2 functions... not to talk about how slow call is.

then if you also need Object.keys(obj) too.... you need to execute another function...

again slower...

so... play with jsperf and test it

Upvotes: 1

GJK
GJK

Reputation: 37369

Array.slice works with array-like objects as well as arrays (like arguments):

Array.prototype.slice.call(obj, 0);

EDIT: As Jonathan Lonowski mentioned, the object will need a correct length property. If you don't have any other properties in the object, you can just count the keys:

obj.length = Object.keys(obj).length;
Array.prototype.slice.call(obj, 0);

EDIT2: The jsPerf shows this not being much slower than using a for loop. So, not the fastest, but definitely short, and not half bad. :)

Upvotes: 2

Carl
Carl

Reputation: 1816

Unsure if this is faster, but an alterntive (Smaller) solution could be

function obj_to_array(obj){
    var result = [];
    for(var i in obj){ 
        var tmp = {}; 
        tmp[i] = obj[i]; 
        result.push(tmp); 
    }
    return result;
 }

Upvotes: 0

bmorenate
bmorenate

Reputation: 963

You seem to have object.1 declared twice, which should result in error.

Try using a general foreach loop to iterate over the object and define your new array.

var i = 0,
    new_array = [];

for (key in obj) {
    new_array[i] = obj[key];
    i++;
}

console.log(new_array);

Upvotes: 0

Related Questions