Home > Back-end >  How do I convert a nested array to a 'keyed' array in JavaScript?
How do I convert a nested array to a 'keyed' array in JavaScript?

Time:12-02

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.

CodePudding user response:

Using Array.reduce. Please check if this works for you. In the below approach ID and Name is hard coded. You can try writing a generic dynamic approach which handle any number of params like ID, Name, Age etc.

const myArray = [
  ["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 obj = myArray.reduce((acc, value, index) => {
  if (index === 0) return acc;
  const key = value[0];

  if (!acc[key]) {
    acc[key] = [];
  }

  acc[key].push({
    ID: value[1],
    Name: value[2]
  });

  return acc;
}, {});

console.log(obj);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

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)
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

In order to achieve what you want, you can follow below steps:

  1. Create an object to store your result.
  2. While you are running the loop you have to check whether name of the organization exists as a key in the object and add it if it does not, initializing it to an empty array. Then push the result you want to store into that array.

Below is a sample implementation, assuming your data is stored in data:

var result = {};
for(var i=1; i < data.length; i  ){
    if(!result.hasOwnProperty(data[i][0])){        
        result[data[i][0]] = [];
    }
    result[data[i][0]].push({ "ID": data[i][1], "Name": data[i][2]});
}
  • Related