Data Mastery
Data Mastery

Reputation: 2085

JavaScript: Restructure and array of objects

I get my data from an API which looks like this:

  desserts: [
    {
      name: ["Frozen Yohurt", "Ice cream Sandwich", "Egg"],
      calories: [159, 237, 109]
    },

My component (Vuetify Datatable) expects the data in a quite different form, like this:

    desserts: [
    { name: "Frozen Yogurt", calories: 159},        
    { name: "Ice cream sandwich", calories: 237 },
     {name: "Egg", calories: 109 }
    ],

I was not able to solve it. This (Creating a JavaScript Object from two arrays) looks quite similar, but gives a different result. Can anyone help me?

Upvotes: 2

Views: 108

Answers (5)

Bhuwan Adhikari
Bhuwan Adhikari

Reputation: 1009

Here is what you can do:

To convert the data into what you want is like this:

const requiredOutput = [];
 
for(let instance of desserts){
  instance.name.forEach((name, index)=>{
    requiredOutput.push({
        name: name,
        calories: instance.calories[index]
    })
  })
}
    
    

Upvotes: 0

Unmitigated
Unmitigated

Reputation: 89159

You can make use of the index parameter in Array#map. Array#flatMap can be used so it works for any number of objects in the array.

let arr = [
    {
      name: ["Frozen Yohurt", "Ice cream Sandwich", "Egg"],
      calories: [159, 237, 109]
    }
];
let res = arr.flatMap(({name,calories}) => 
  name.map((name,idx)=>({name,calories:calories[idx]})));
console.log(res);

Upvotes: 1

Kunal Mukherjee
Kunal Mukherjee

Reputation: 5853

Use Array.prototype.reduce to flatten each item to your desired structure

const obj = {
  desserts: [{
    name: ["Frozen Yohurt", "Ice cream Sandwich", "Egg"],
    calories: [159, 237, 109]
  }]
};

const result = obj.desserts.reduce((acc, { name, calories }) => {
  Array.prototype.push.apply(acc, name.map((item, idx) => ({
    name: item,
    calories: calories[idx]
  })));
  return acc;
}, []);

console.log(result);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386540

You could reduce the object's entries and map the found values along with the key as objects.

This approach takes only the first object found in the desserts array.

const
    desserts = { name: ["Frozen Yohurt", "Ice cream Sandwich", "Egg"], calories: [159, 237, 109] },
    result = Object
        .entries(desserts)
        .reduce((r, [k, values]) => values.map((v, i) => ({ ...r[i], [k]: v })), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Majed Badawi
Majed Badawi

Reputation: 28404

You can make this in one iteration per object. Just make sure the two arrays have equal lengths:

let desserts = [
    {
      name: ["Frozen Yohurt", "Ice cream Sandwich", "Egg"],
      calories: [159, 237, 109]
    }
];

let list = [];
for(let i = 0; i < desserts.length; i++){
     let obj = desserts[i];
     if(obj.name.length == obj.calories.length){
          for(let i = 0; i < obj.name.length; i++){
               list.push({name: obj.name[i], calories: obj.calories[i]});
          }
     }
}
console.log(list);

Upvotes: 1

Related Questions