43

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??

4
  • I would like to know how to do it both ways.. Commented Apr 26, 2012 at 15:44
  • please, remember to always provide some code identation, it makes the question easier to read Commented Apr 26, 2012 at 15:45
  • thanks for the edit...will remember it nxt time.. Commented Apr 26, 2012 at 15:47
  • 2
    Note that JavaScript has no "hash map", just "objects". Commented Apr 26, 2012 at 16:10

8 Answers 8

44

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));

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

9 Comments

I suggest checking hasOwnProperty inside the for...in loop.
@Rocket I do NOT suggest checking hasOwnProperty inside the for...in loop.
@AnuragUniyal: Please explain why.
@Rocket: Why would someone do that if they haven't extended Object.prototype?
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.
|
28

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.

Comments

11

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.

Comments

7

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?

Comments

1

It looks simple, key of your map is type and values are name, so just loop thru map and insert object in a list e.g.

var d = { "fruit" : ["mango","orange"],"veg" :["carrot"]} 
var l = []
for(var type in d){
    l.push({'type':type, 'name': d[type]})
}
console.log(l)

output:

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

35 Comments

as a good practice it's better to also use .hasOwnProperty() method
@F.Calderan why that is necessary in this case, when format is fixed map?
I didn't say it's necessary but we can't say if that object has some other properties added via Object.prototype
@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.
@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
|
1

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]

Comments

0

In case of using underscore.js:

var original = { 
   "fruit" : ["mango","orange"],
   "veg"   : ["carrot"]
}
var converted = _.map(original, function(name, type){
   return {
      type: type, 
      name: name
   };
});

Comments

-1

No Need of loop

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


};  

var b = [  
    { "type" : "fruit" , "pop" : function(){this.name = a[this.type]; delete this.pop; return this} }.pop() ,          
    { "type" : "veg" ,   "pop" : function(){this.name = a[this.type]; delete this.pop; return this} }.pop()   
]

1 Comment

that's...bizarre. at least reuse the function ;)

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.