Skip to content
Advertisement

How to recalculate an object from a nested objects?

I have an object where Citems is an array of Object. Each object has status on or of and time.

{
  Chapter: [
    {
      Cname: 'chapter 1',
      Citems: [{status: 'on', time: 30},{status: 'on', time: 60}],
      
    },
    {
      Cname: 'chapter 2',
      Citems: [{status: 'on', time: 30},{status: 'off', time: 60}]
    }
  ],
  name: 'Something',
  description: 'jfdgljfgdfjgldfkjglfd'
}

I want to generate an array or object from it that show total time for each status like below

{
on: 120,
off: 60
}

I tried with map and reduce but getting confused.

Advertisement

Answer

You just need a nested ‘sum’, here implemented using reduce() and making use of computed properties to update the accumulator using the status as key.

const data = { Chapter: [{ Cname: 'chapter 1', Citems: [{ status: 'on', time: 30 }, { status: 'on', time: 60 }], }, { Cname: 'chapter 2', Citems: [{ status: 'on', time: 30 }, { status: 'off', time: 60 }] }], name: 'Something', description: 'jfdgljfgdfjgldfkjglfd' };

const result = data.Chapter.reduce((a, { Citems }) => {
  for (const { status, time } of Citems) {
    a[status] += time;
  }
  return a;
}, { on: 0, off: 0 });

console.log(result);

Or using a for...of loop

const data = { Chapter: [{ Cname: 'chapter 1', Citems: [{ status: 'on', time: 30 }, { status: 'on', time: 60 }], }, { Cname: 'chapter 2', Citems: [{ status: 'on', time: 30 }, { status: 'off', time: 60 }] }], name: 'Something', description: 'jfdgljfgdfjgldfkjglfd' }

const result = { on: 0, off: 0 };

for (const { Citems } of data.Chapter) {
  for (const { status, time } of Citems) {
    result[status] += time;
  }
}

console.log(result);

To extend this to an array of such Chapter objects you could nest it once more in a reduce().

const data = [
  {
    Chapter: [{ Cname: 'chapter 1', Citems: [{ status: 'on', time: 30 }, { status: 'on', time: 60 }], }, { Cname: 'chapter 2', Citems: [{ status: 'on', time: 30 }, { status: 'off', time: 60 }] }],
    name: 'Something',
    description: 'jfdgljfgdfjgldfkjglfd'
  },
  {
    Chapter: [{ Cname: 'chapter 1', Citems: [{ status: 'on', time: 30 }, { status: 'off', time: 30 }], }, { Cname: 'chapter 2', Citems: [{ status: 'on', time: 30 }, { status: 'off', time: 60 }] }],
    name: 'Something2',
    description: 'asdfasdfasdfasdfasdfa'
  }
]

const result = data.reduce((a, { name, Chapter }) => {
  a[name] = Chapter.reduce((a, { Citems }) => {
    for (const { status, time } of Citems) {
      a[status] += time;
    }
    return a;
  }, { on: 0, off: 0 });

  return a;
}, {});

console.log(result);
Advertisement