Skip to content

How do I convert a nested array to a ‘keyed’ array in JavaScript?

I have a nested array that looks like this:

[["Organisation","ID","Name"],["ACME","123456","Bart Simpson"],["ACME","654321","Ned Flanders"],["ACME","1234","Edna Kabappel"],["Yahoogle","666666","Bon Scott"],["Yahoogle","99999","Neil Young"],["Yahoogle","111111","Shania Twain"]]

The first value in each array is the name of an organisation that an ID and name can belong to.

I am trying to find the simplest way to group all instances where an ID and name belong to the same company, under one ‘key’.

So the above would result in something like this:

{
   "ACME": [
      {
         "ID": 123456,
         "Name": "Bart Simpson"
      },
      {
         "ID": 654321,
         "Name": "Ned Flanders"
      },
      {
         "ID": 1234,
         "Name": "Edna Kabappel"
      }
   ],
   "Yahoogle": [
      {
         "ID": 666666,
         "Name": "Bon Scott"
      },
      {
         "ID": 99999,
         "Name": "Neil Young"
      },
      {
         "ID": 111111,
         "Name": "Shania Twain"
      }
   ]
}

I have been playing around with for loops but I’m ending up with many many lines of code, trying to detect when the company name is different from the previous, and getting into a real mess with things.

I have searched a lot here trying to find something similar but have not had any luck.

I have only just started coding again for person interest after about 18 years and I’m very novice again.

Thank you in advance for any assistance.

Answer

lot of solutions to arrive at same result, one using lambda and reduce: this is a generic solution, just adapt the output push to build your final json.

const datas = [
  ["Organisation", "ID", "Name"],
  ["ACME", "123456", "Bart Simpson"],
  ["ACME", "654321", "Ned Flanders"],
  ["ACME", "1234", "Edna Kabappel"],
  ["Yahoogle", "666666", "Bon Scott"],
  ["Yahoogle", "99999", "Neil Young"],
  ["Yahoogle", "111111", "Shania Twain"]
];

const titles = datas.shift()
const groupBy = (x,f)=>x.reduce((a,b)=>((a[f(b)]||=[])
                        .push({[titles[1]]:b[1], [titles[2]]:b[2]}),a),{});

const result = groupBy(datas, v => v[0])

console.log(result)