Home > Net >  Converting an array of weeks/day to an organized object
Converting an array of weeks/day to an organized object

Time:10-01

I have an array of objects that have a format like this:

const program = [
  { id: '1', week: 1, day: 1, description: 'week 1 day 1', completed: true },
  { id: '2', week: 1, day: 2, description: 'week 1 day 2', completed: true },
  { id: '3', week: 1, day: 3, description: 'week 1, day 3', completed: true },
  { id: '4', week: 2, day: 1, description: 'week 2, day 1', completed: true },
  { id: '5', week: 2, day: 2, description: 'week 2 day 2', completed: false },
  { id: '6', week: 2, day: 3, description: 'week 2 day 3', completed: true },
  { id: '7', week: 3, day: 1, description: 'week 3, day 1', completed: false },
  // ....
  { id: '89', week: 11, day: 9, description: 'week 11, day 9', completed: false },
  // ...
];

and I want the output to look something like this:

const weekMap = {
  1: [
    { id: '1', week: 1, day: 1, description: 'week 1 day 1', completed: true },
    { id: '2', week: 1, day: 2, description: 'week 1 day 2', completed: true },
    { id: '3', week: 1, day: 3, description: 'week 1, day 3', completed: true },
  ],
  2: [
    { id: '4', week: 2, day: 1, description: 'week 2, day 1', completed: true },
    { id: '5', week: 2, day: 2, description: 'week 2 day 2', completed: false },
    { id: '6', week: 2, day: 3, description: 'week 2 day 3', completed: true },
  ],
  3: [
    { id: '7', week: 3, day: 1, description: 'week 3, day 1', completed: false },
    // ....
  ],
  11: [
    { id: '89', week: 11, day: 9, description: 'week 11, day 9', completed: false },
    // ....
  ],
};

So far what I've tried was .reduce

export const toWeekMap = (programSteps) =>
  programSteps.reduce((acc, curr) => {
    if (!acc[curr.week]) {
      acc[curr.week] = [];
    }

    if (!acc[curr.week][curr.day]) {
      acc[curr.week][curr.day] = [];
    }

    console.log(acc);

    return acc[curr.week][curr.day].push(curr);
  }, {});

Though this doesn't work and I'm not sure of any ways around it. The error I get is

Uncaught TypeError: Cannot create property '1' on number '1'

Obviously there's something very off with my logic... maybe I'm misunderstanding .reduce?

CodePudding user response:

Hello you can try this :

 export const toWeekMap = (programSteps) =>
        programSteps.reduce((acc, curr) => {
           (acc[curr.week] = acc[curr.week] || []).push(curr);
            return acc;
    }, {});

CodePudding user response:

The main mistake of your code is in this line:

return acc[curr.week][curr.day].push(curr);

This is the equivalent of saying:

const a = acc[curr.week][curr.day].push(curr);
return a;

a will contain the return value of the push function, which is the new length of the array.

What you actually want to do is:

acc[curr.week][curr.day].push(curr);
return acc;

After that, you can fix your logic inside the reduce according to your needs. If I understood correctly what you want, this should do:

const program = [
  { id: '1', week: 1, day: 1, description: 'week 1 day 1', completed: true },
  { id: '2', week: 1, day: 2, description: 'week 1 day 2', completed: true },
  { id: '3', week: 1, day: 3, description: 'week 1, day 3', completed: true },
  { id: '4', week: 2, day: 1, description: 'week 2, day 1', completed: true },
  { id: '5', week: 2, day: 2, description: 'week 2 day 2', completed: false },
  { id: '6', week: 2, day: 3, description: 'week 2 day 3', completed: true },
  { id: '7', week: 3, day: 1, description: 'week 3, day 1', completed: false },
  // ....
  { id: '89', week: 11, day: 9, description: 'week 11, day 9', completed: false },
  // ...
];


const toWeekMap = (programSteps) =>
  programSteps.reduce((acc, curr) => {
  
    if (!acc[curr.week]) {
      acc[curr.week] = [];
    }


     acc[curr.week].push(curr);
     return acc;
  }, {});
  console.log(toWeekMap(program))

CodePudding user response:

The usage of the reduce is good. However, the logic of building the desired object is flawed at one point. Here is the correction

export const toWeekMap = (programSteps) =>
  programSteps.reduce((acc, curr) => {

    if (!acc[curr.week]) {
      acc[curr.week] = [];
    }


    acc[curr.week].push(curr);   //<<<--- compare here


    console.log(acc);


    return acc[curr.week][curr.day].push(curr);
  }, {});
  • Related