Search code examples
javascriptarraysobjectforeachnested-loops

Get all links for each associated id in object of array


Given an array of objects, where a URL has an array of objects, each with an ID:

[
  {
    "url": "http://www.example.com/something",
    "ids": [
      { "id": "U30", "type": "a11y-unknown" },
      { "id": "RC30", "type": "a11y-unknown" }
    ]
  },
  {
    "url": "http://www.example.com/something-else",
    "ids": [
      { "id": "U30", "type": "a11y-unknown" },
      { "id": "RC32", "type": "a11y-ready" }
    ]
  }
]

I'm trying to loop over the array, then the array of ids and grab the id (U30 for example) and organize the urls by ID.

The end result should look like:

{
  "U30": {
    "type": "a11y-unknown",
    "urls": [
      "http://www.example.com/something",
      "http://www.example.com/something-else"
    ]
  }
},
{
  "RC30": {
    "type": "a11y-ready",
    "urls": [
      "http://www.example.com/something"
    ]
  }
},
{
  "RC32": {
    "type": "a11y-unknown",
    "urls": [
      "http://www.example.com/something-else"
    ]
  }
}

I'm doing the following which gives me the URL's, but I can't get the associated id to be the key at the top, as well as the type value as another property for each ID.

const output = {};
sites.forEach(obj => {
  const ids = obj.ids
  if (ids && ids.length > 0) {
    ids.forEach(id => {
      if (!output[id]) {
        output[id] = {length: 0, urls: []}
      }
      output[id].urls.push(obj.url);
      output[id].length++;
    });
  }
});

Solution

  • const data = [
      {
        "url": "http://www.example.com/something",
        "ids": [
          { "id": "U30", "type": "a11y-unknown" },
          { "id": "RC30", "type": "a11y-unknown" }
        ]
      },
      {
        "url": "http://www.example.com/something-else",
        "ids": [
          { "id": "U30", "type": "a11y-unknown" },
          { "id": "RC32", "type": "a11y-ready" }
        ]
      }
    ]
    
    const grouped = {}
    for (const obj of data) {
      for (const idObj of obj.ids) {
        if (!grouped[idObj.id]) {
          grouped[idObj.id] = {
            urls: [],
            type: idObj.type
          }
        }
        grouped[idObj.id].urls.push(obj.url)
      }
    }
    
    console.log(grouped)