Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a set of data in the format:

[{"title":movietitle1, "id":445, "release":"16JUN1985"}, {"title":movietitle2, "id":487, "release":"12AUG1993"}]

Which I need to convert into JSON formatted as such:

{ "movietitle1":{"id":445,"release":"16JUN1985"}, "movietitle2":{"id":487, "release":"12AUG1993"} }

I don't have any idea of how to make this happen.

share|improve this question
    
I recommend reading one of the plethora of javascript tutorials to teach yourself how to do this. –  Daniel Apr 27 at 3:08
1  
The format you currently have is a lot more useful. Still, you should try before you ask. –  Bill Criswell Apr 27 at 3:09
1  
does it make any difference for you? Please explain more what are you try to do with the new format? –  alpham8 Apr 27 at 3:12

3 Answers 3

up vote 2 down vote accepted

You can do this with JSON.stringify() and some basic data manipulation.

Store your data in a variable, lets call it input_data.

Loop through your data and use each entry to build up another variable, lets call it output_data.

// create an object to store the newly formatted data
var output_data = {};
// the code in here is run once for each item in input_data
for (var i = 0; i < input_data.length; i++) {
  // get the current item's title
  var title = input_data[i].title;
  // use the title as the key in the output data
  //  and assign the other values to that key
  output_data[title] = {
    id: input_data[i].id,
    release: input_data[i].release
  };
} 

// use JSON.stringify() to make a valid JSON string
var json = JSON.stringify(output_data);

// now use the variable json which contains your JSON string
share|improve this answer
    
"Minimize number of variables. Inline variables which are used only once. Take advantage of foreach loops." Spartan Programming –  Sukima Apr 27 at 3:35
    
Did you have a point with that? I see you suggested using underscore. You realize that underscore's map function also has to create a variable internally... Just because you don't create a variable doesn't mean your code is more efficient. Besides, making one variable for output and another for an iterator versus loading a whole library? come on... This is very lean and efficient compared to that. –  jshanley Apr 27 at 3:43
    
@Sukima By the way, take a look at the suggested Polyfill for Array.prototype.forEach(). It's just a much more complicated version of what I did here... –  jshanley Apr 27 at 3:48
    
I was not commenting on efficiency. You are correct on a small scale. (How many cycles need saving?). I was commenting on readability / complexity. All subjective so take it with a grain of salt. –  Sukima Apr 27 at 3:48
    
@Sukima I see what you're saying. The point was to spell things out for the purpose of teaching. Sometimes breaking things down into multiple steps makes them easier to digest, though it's not necessarily the best-looking code. Making a separate variable for title is completely unnecessary in terms of the function of the code, but does help to illustrate exactly what is happening. –  jshanley Apr 27 at 3:50

What you are asking for is to turn an array into a map , keying by a specific property, If you really want JSON, you can just call JSON.stringify on the resulting JS object.

http://jsfiddle.net/FfE8f/1/

/**
 * Given an array and a property name to key by, returns a map that is keyed by each array element's chosen property
 * This method supports nested lists
 * Sample input: list = [{a: 1, b:2}, {a:5, b:7}, [{a:8, b:6}, {a:7, b:7}]]; prop = 'a'
 * Sample output: {'1': {a: 1, b:2}, '5': {a:5, b:7}, '8': {a:8, b:6}, '7':{a:7, b:7}}
 * @param {object[]} list of objects to be transformed into a keyed object
 * @param {string} keyByProp The name of the property to key by
 * @return {object} Map keyed by the given property's values
 */
function mapFromArray (list , keyByProp) {
  var map = {};
  for (var i=0, item; item = list[i]; i++) {
    if (item instanceof Array) {
      // Ext.apply just copies all properties from one object to another,
      // you'll have to use something else. this is only required to support nested arrays.
      Ext.apply(map, mapFromArray(item, keyByProp));
    } else {
      map[item[keyByProp]] = item;
    }
  }
  return map;
};

console.log(mapFromArray([
    {"title": "title 1", "id":445, "release":"16JUN1985"}, 
    {"title":"movietitle2", "id":487, "release":"12AUG1993"}],
    "title"
)));
// outputs
{
    "title 1": {"title":"title 1","id":445,"release":"16JUN1985"},
    "movietitle2": {"title":"movietitle2","id":487,"release":"12AUG1993"}
} 

See More efficient way to search an array of javascript objects?

share|improve this answer
    
This looks complex. Maybe forEach can help simplify it? It works just feels a little "there be dragons"-ish. Also where is Ext defined? –  Sukima Apr 27 at 3:29
    
@Sukima Ext is a library I use, the comments say you should write your own if you need to support nested arrays. What are you having a hard time grasping? –  Juan Mendes Apr 27 at 15:07

Your mixing terms. I'm assuming you're asking about manipulating data with JavaScript objects and not strings with JSON data. (The later can be converted with JSON.parse).

First iterate over the array and assigning to an object. This kind of data manipulation works well using Underscore, check it out.

In vanilla JS lets try something like this:

var newData = {};
data.forEach(function(item) {
  var title = item.title;
  delete item.title;
  newData[title] = item;
});

A little crufty but gets the job done.

Personally I'd use this Underscore version:

var newData = _(data).chain()
  .map(function(item) {
    return [item.title, _(item).omit('title')];
  })
  .object()
  .value();
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.