How to convert JS Object to Array

81,269

Solution 1

You can do it like this (in a working snippet):

var input = { 
    "fruit" : ["mango","orange"],
    "veg"   : ["carrot"]
} 

var output = [], item;

for (var type in input) {
    item = {};
    item.type = type;
    item.name = input[type];
    output.push(item);
}

// display result
document.write(JSON.stringify(output));

Or, if you or someone else has been extending the Object prototype with enumerable properties (which I think is a bad practice personally), then you could use this to protect from that:

var input = { 
    "fruit" : ["mango","orange"],
    "veg"   : ["carrot"]
} 

var output = [], item;

for (var type in input) {
    if (input.hasOwnProperty(type)) {
        item = {};
        item.type = type;
        item.name = input[type];
        output.push(item);
    }
}

// display result
document.write(JSON.stringify(output));

And, using some more modern functionality:

var input = { 
    "fruit" : ["mango","orange"],
    "veg"   : ["carrot"]
};

var output = Object.keys(input).map(function(key) {
   return {type: key, name: input[key]};
});

// display the result
document.write(JSON.stringify(output));

Solution 2

In a browser that supports ES5 – or where you added a shim for it:

var stuff = { 
    "fruit" : ["mango","orange"],
    "veg"   : ["carrot"]
}

var array = Object.keys(stuff).map(function(key) {
    return {"type" : key, "name" : stuff[key] }
})

See: Object.keys, Array's map

Or, in the old fashion way:

var stuff = { 
    "fruit" : ["mango","orange"],
    "veg"   : ["carrot"]
}

var array = []

for (var key in stuff) {
    if (stuff.hasOwnProperty(key)) {
        array.push({"type" : key, "name" : stuff[key] })
    }
}

Please notice that in both cases the array's value are shared because in JS the objects are passed by reference. So, for instance, stuff["fruit"] and array[0].name points to the same reference of the array ["mango", "orange"]. It means, if you change one of them, the other will be changed as well:

stuff["fruit"].push("apple");
alert(array[0].name); // "mango", "orange", "apple"

To avoid that, you can use slice to have a one-level deep copy of your array. So in the code above, instead of:

"name" : stuff[key]

you will have:

"name" : stuff[key].slice(0)

Hope it helps.

Solution 3

For those using ES6 maps...

Assuming you have...

const m = new Map()
m.set("fruit",["mango","orange"]);
m.set("veg",["carrot"]);

You can use...

const arr = Array.from(map, ([key, val]) => {
  return {type: key, name: val};
});

Note that Array.from takes iterables as well as array-like objects.

Solution 4

I would like to give an "oneline" solution:

var b = Object.keys(a).map(e => { return { type:e, name:a[e] } });

Economy of words at your service. Question asked for translating an object to an array, so I'm not duplicating above answer, isn't it?

Solution 5

Not exactly the answer you are looking for, but it could be useful for general purpose.

var hash2Array = function(hash, valueOnly) {
  return Object.keys(hash).map(function(k) {
    if (valueOnly) {
      return hash[k];
    } else {
      var obj={};
      obj[k] = hash[k];
      return obj;
    }
  });
};

//output
hash2Array({a:1, b:2});     // [{a:1}, {b:2}]
hash2Array({a:1, b:2},true) // [1,2]
Share:
81,269
Sam
Author by

Sam

Everthing JS. 7 year experience with start up companies. ~5years with remote distributed teams. Loves visualizing data.

Updated on July 09, 2022

Comments

  • Sam
    Sam almost 2 years

    I need to convert a hash map

    { 
        "fruit" : ["mango","orange"],
        "veg"   : ["carrot"]
    } 
    

    to

    [ 
      { "type" : "fruit" , "name" : ["mango","orange"] } ,
      { "type" : "veg" ,   "name" : ["carrot"] } 
    ]
    

    how do I do that??

  • Fabrizio Calderan
    Fabrizio Calderan about 12 years
    as a good practice it's better to also use .hasOwnProperty() method
  • Nandhini
    Nandhini about 12 years
    @F.Calderan why that is necessary in this case, when format is fixed map?
  • gen_Eric
    gen_Eric about 12 years
    @AnuragUniyal: Because without hasOwnProperty, your for... in loop will read values from up the prototype chain. For example Object.prototype.test = 'test'. Your loop will read this value, hasOwnProperty checks to see if the value is from the object itself, and not its prototype chain.
  • Fabrizio Calderan
    Fabrizio Calderan about 12 years
    I didn't say it's necessary but we can't say if that object has some other properties added via Object.prototype
  • gen_Eric
    gen_Eric about 12 years
    I suggest checking hasOwnProperty inside the for...in loop.
  • Sam
    Sam about 12 years
    so, what if it is not a fixed map??
  • Admin
    Admin about 12 years
    @F.Calderan: Unless you have code that adds enumerable properties to Object.prototype, it isn't necessary. It does not make any sense to use hasOwnProperty if you haven't done that.
  • Nandhini
    Nandhini about 12 years
    @F.Calderan in will depend on the problem and how dict was constructed but in this scenario I will discourage such usage when I know I have a plain JavaScript object, it is like premature optimization and decreases readablity
  • Nandhini
    Nandhini about 12 years
    @Sam by fixed map I know it has required properties and you have created it thru normal object creation or from json, it will work for all such maps.
  • Nandhini
    Nandhini about 12 years
    @Rocket I do NOT suggest checking hasOwnProperty inside the for...in loop.
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: I think it's good to use hasOwnProperty anyway, so if there's ever a case where's it's needed, you won't forget. :-P
  • Fabrizio Calderan
    Fabrizio Calderan about 12 years
    it is not about premature optimization: it's only just good practice and headaches prevention
  • gen_Eric
    gen_Eric about 12 years
    @AnuragUniyal: Please explain why.
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: What I run Object.prototype.test = 'test' on your page? hasOwnProperty will prevent me from breaking your page :-)
  • Admin
    Admin about 12 years
    @Rocket: Why would someone do that if they haven't extended Object.prototype?
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: What if I decide to run Object.prototype.test = 'test' on your page, just for the hell of it. BAM! Broke your script :-P
  • Nandhini
    Nandhini about 12 years
    @Rocket in that case why not check that if key is not a function, or many such checks or may in some case we do want parent properties so add an option for that too
  • Admin
    Admin about 12 years
    @Rocket: I don't understand. How is your code getting on my page? :)
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: JavaScipt console. javascript:Object.prototype.test = 'test' in the address bar. Greasemonkey script/browser plugin. Plenty of ways.
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: JavaScipt console. javascript:Object.prototype.test = 'test' in the address bar. Greasemonkey script/browser plugin. Plenty of ways.
  • Nandhini
    Nandhini about 12 years
    @Rocket see my question for discussion, it is anyway not place for such extended dicussions
  • Admin
    Admin about 12 years
    @Rocket: That doesn't make much sense. Why would a person sabotage the page they're visiting? If they want to do that, it's fine, but it's an academic point at best.
  • gen_Eric
    gen_Eric about 12 years
    @AnuragUniyal: Object.prototype.myArray = [1,2,3]. This isn't a function. Why check for every scenario when hasOwnProperty is easy? :-P
  • Nandhini
    Nandhini about 12 years
    @Rocket what about some one inserting wrong fruits e.g mymapp['fruits'] = 'bacon', or adding a function directly to my object so I filter them out too
  • Fabrizio Calderan
    Fabrizio Calderan about 12 years
    @amnotiamIt's not a matter of sabotage: what if another js library makes addition to Object.prototype. How can you be sure that this won't never happen?
  • gen_Eric
    gen_Eric about 12 years
    @AnuragUniyal: What are you talking about? That's why you never use global variables :-P
  • jfriend00
    jfriend00 about 12 years
    I gave the OP either option in my answer (with or without hasOwnProperty()). I don't personally allow extension of Object in my pages so I don't have to add extra code to protect from it. If I was in an environment where that was a possibility, I would code to protect from it.
  • Admin
    Admin about 12 years
    @F.Calderan: Ignorance of the code you're using isn't a very good argument. A programmer should know what a library does before using it. If it extends Object.prototype, you should stop using it. And Rocket's example was one of sabotage.
  • Nandhini
    Nandhini about 12 years
    @Rocket that is why libraries should not modify object prototype and if lib do that don't use it, I am full control on my pages
  • Admin
    Admin about 12 years
    @F.Calderan: And to your question "How can you be sure that this won't never happen?", it's trivial to test for Object.prototype extensions if you're really that worried about it.
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: What if this array was then sent to a server via AJAX. What if I'm an evil hacker? Enough of the "what if"s. hasOwnProperty will make sure your array is what you want. Object.prototype can be extended legitimately. I think it's a good habit to use hasOwnProperty, so you don't forget when it's really needed. It'll save headaches.
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: hasOwnProperty is even more trivial, and less code :-P
  • Admin
    Admin about 12 years
    @Rocket: If you've been hacked, Object.prototype is the least of your concerns. An AJAX request makes no difference. You should know the code you're using.
  • Admin
    Admin about 12 years
    @Rocket: hasOwnProperty for every property in every enumeration you do is more code, and more overhead. Why check every property in ever enumeration, when you could check once in the beginning?
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: Sometimes it's the simple things that get hacked. The spot where you'd never look. Your weak spot.
  • Admin
    Admin about 12 years
    @Rocket: Then you must guard against every built in object and property that could possibly be modified. Right?
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: Why the heck would you do for(var i in 12) or for(var i in "dog")?
  • Admin
    Admin about 12 years
    @Rocket: I don't know what you mean.
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: Why does it matter if other prototypes are extended? You're never gonna be looping over 'em? Anyway, I don't want to argue too much. I've just always been taught to use hasOwnProperty, and I haven't heard many good arguments why I shouldn't.
  • Nandhini
    Nandhini about 12 years
    @Rocket if somebody can modify object without me knowing then he can change e.g. Array.prototype.join = function(){alert("hacked!")} now will you say I should be using any array methods at all
  • Admin
    Admin about 12 years
    @Rocket: I wasn't talking about other prototypes being extended. I meant that if hackers go for the small stuff, you'd need to guard against any and all possible modifications to the environment. For example, what if someone does Object.prototype.hasOwnProperty = function() { alert('foo'); }?
  • gen_Eric
    gen_Eric about 12 years
    @amnotiam: Yeah, I guess you're right. I didn't think of that. X_X You win :-P Thanks for a fun argument, I learned something new :-D
  • Tim Post
    Tim Post about 12 years
    If you want to continue this discussion, please use Stack Overflow Chat.
  • drzaus
    drzaus almost 10 years
    that's...bizarre. at least reuse the function ;)
  • jfriend00
    jfriend00 over 8 years
    Added a more modern version using Object.keys() and .map() and made all the examples into working snippets.