Drew Szurko
Drew Szurko

Reputation: 1621

How can I add levels to a JSON array?

I have a JSON array of 7,000 objects, which are all under one parent. I want to add two levels in front of them, a year level, then a month level.

Currently my structure looks like:

{
//apod is single representation of main parent
  "apod" : {
//below is a unique identifier with nested data
      "-KgpW6owlA2YGwKFj2V-" : {
          "date" : "1995-06-16",
          "explanation" : "If the Earth could somehow be transformed to the ultra-high density of a neutron star , it might appear as it does in the above computer generated figure. Due to the very strong gravitational field, the neutron star distorts light from the background sky greatly. If you look closely, two images of the constellation Orion are visible. The gravity of this particular neutron star is so great that no part of the neutron star is blocked from view - light is pulled around by gravity even from the back of the neutron star.",
          "gsHdUrl" : "https://www.foo.com",
          "gsThumbnailUrl" : "https://www.foo.com",
          "hdurl" : "https://apod.nasa.gov/apod/image/e_lens.gif",
          "media_type" : "image",
          "service_version" : "v1",
          "title" : "Neutron Star Earth",
          "url" : "https://apod.nasa.gov/apod/image/e_lens.gif"
      },
//below is another unique identifier with nested data
      "-KgpW7fV9laX8YL30glD" : {
          "date" : "1995-06-20",
          "explanation" : "Today's Picture: June 20, 1995    The Pleiades Star Cluster  Picture Credit: Mount Wilson Observatory  Explanation:  The Pleiades star cluster, M45, is one of the brightest star clusters visible in the northern hemisphere. It consists of many bright, hot stars that were all formed at the same time within a large cloud of interstellar dust and gas. The blue haze that accompanies them is due to very fine dust which still remains and preferentially reflects the blue light from the stars.   We keep an archive of previous Astronomy Pictures of the Day.   Astronomy Picture of the Day is brought to you by  Robert Nemiroff and  Jerry Bonnell . Original material on this page is copyrighted to Robert J. Nemiroff and Jerry T. Bonnell.",
          "gsHdUrl" : "https://www.foo.com",
          "gsThumbnailUrl" : "https://www.foo.com",
          "hdurl" : "https://apod.nasa.gov/apod/image/pleiades2.gif",
          "media_type" : "image",
          "service_version" : "v1",
          "title" : "Pleiades Star Cluster",
          "url" : "https://apod.nasa.gov/apod/image/pleiades2.gif"
      }
}

What I want to transform it to would look like:

{
"apod": {
    "1995": {
        "06": {
            "-KgpW6owlA2YGwKFj2V-": {
                "date": "1995-06-16",
                "explanation": "If the Earth could somehow be transformed to the ultra-high density of a neutron star , it might appear as it does in the above computer generated figure. Due to the very strong gravitational field, the neutron star distorts light from the background sky greatly. If you look closely, two images of the constellation Orion are visible. The gravity of this particular neutron star is so great that no part of the neutron star is blocked from view - light is pulled around by gravity even from the back of the neutron star.",
                "gsHdUrl": "https://www.foo.com",
                "gsThumbnailUrl": "https://www.foo.com",
                "hdurl": "https://apod.nasa.gov/apod/image/e_lens.gif",
                "media_type": "image",
                "service_version": "v1",
                "title": "Neutron Star Earth",
                "url": "https://apod.nasa.gov/apod/image/e_lens.gif"
            },
            "-KgpW7fV9laX8YL30glD": {
                "date": "1995-06-20",
                "explanation": "Today's Picture: June 20, 1995    The Pleiades Star Cluster  Picture Credit: Mount Wilson Observatory  Explanation:  The Pleiades star cluster, M45, is one of the brightest star clusters visible in the northern hemisphere. It consists of many bright, hot stars that were all formed at the same time within a large cloud of interstellar dust and gas. The blue haze that accompanies them is due to very fine dust which still remains and preferentially reflects the blue light from the stars.   We keep an archive of previous Astronomy Pictures of the Day.   Astronomy Picture of the Day is brought to you by  Robert Nemiroff and  Jerry Bonnell . Original material on this page is copyrighted to Robert J. Nemiroff and Jerry T. Bonnell.",
                "gsHdUrl": "https://www.foo.com",
                "gsThumbnailUrl": "https://www.foo.com",
                "hdurl": "https://apod.nasa.gov/apod/image/pleiades2.gif",
                "media_type": "image",
                "service_version": "v1",
                "title": "Pleiades Star Cluster",
                "url": "https://apod.nasa.gov/apod/image/pleiades2.gif"
            }
        },
        "07": {}
    },
    "1996": {}
}
}

I want to keep the key->object mapping. What would be the best way to loop through this and restructure it? I'm somewhat lost as I haven't worked with editing/restructuring JSON that much.

Thank you

Upvotes: 0

Views: 147

Answers (2)

pishpish
pishpish

Reputation: 2614

What you have are objects, not arrays. Anyway, I commented things out.

function convert( json ){

  // `data` is a JavaScript object we get from parsing
  // json. For simplicity we remove the `apod` property
  // and add it prior to returning.
  let data;
  try {
    data = JSON.parse(json).apod;
  }
  catch(e){
    alert("invalid json!");
  }

  // Create a new object to store the mapped objects.
  // We will convert this to a json string in the end.
  const result = {};

  // Iterate all properties.
  const keys = Object.keys(data);
  for( let key of keys ){

    // Parse month and year.
    const [year, month] = data[key].date.split("-", 2);

    // If there hadn't been an occurrence of this year,
    // introduce an object.
    if( !result[year] )
      result[year] = {};

    // If there hadn't been an occurrence of this month
    // in this year, introduce an object.
    if( !result[year][month] )
      result[year][month] = {};

    // Add element to current year and month.
    result[year][month][key] = data[key];
  }

  // Convert and return the mapped object as json.
  return JSON.stringify({ apod: result });

}

Upvotes: 1

mochalygin
mochalygin

Reputation: 742

{
    "2015": {
        "01": [{...}, {...}, ...],
        "02": [{...}, ...],
        ...
        "12": [...]
    },
    "2016": {
        ...
    }
}

To loop via PHP you can:

foreach ($data as $year => $monthes) {
    foreach ($monthes as $month => $objects) {
        foreach ($objects as $object) {
            // do something with $year, $month and $object
        }
    }
}

Upvotes: 0

Related Questions