skip to Main Content

I have 2 array. As a result, I should get 1 array. If "groupPoint" matches, then take the data from the "data" array.

initialData = [
{groupPoint: '00:00', soldLeads: 0},
{groupPoint: '01:00', soldLeads: 0},
{groupPoint: '02:00', soldLeads: 0},
{groupPoint: '03:00', soldLeads: 0},
{groupPoint: '04:00', soldLeads: 0},
{groupPoint: '05:00', soldLeads: 0},
{groupPoint: '06:00', soldLeads: 0},
{groupPoint: '07:00', soldLeads: 0},
{groupPoint: '08:00', soldLeads: 0},
{groupPoint: '09:00', soldLeads: 0},
{groupPoint: '10:00', soldLeads: 0},
]

data = [
{groupPoint: '03:00', soldLeads: '4'},
{groupPoint: '04:00', soldLeads: '1'},
{groupPoint: '07:00', soldLeads: '1'}
]

The result should be:

result = [
{groupPoint: '00:00', soldLeads: 0},
{groupPoint: '01:00', soldLeads: 0},
{groupPoint: '02:00', soldLeads: 0},
{groupPoint: '03:00', soldLeads: '4'},
{groupPoint: '04:00', soldLeads: 0},
{groupPoint: '05:00', soldLeads: 0},
{groupPoint: '06:00', soldLeads: 0},
{groupPoint: '07:00', soldLeads: '4'},
{groupPoint: '08:00', soldLeads: '1'},
{groupPoint: '09:00', soldLeads: 0},
{groupPoint: '10:00', soldLeads: 0},
]

But I have the result:

initialData = [
{groupPoint: '00:00', soldLeads: 0},
{groupPoint: '01:00', soldLeads: 0},
{groupPoint: '02:00', soldLeads: 0},
{groupPoint: '03:00', soldLeads: '4'},
{groupPoint: '03:00', soldLeads: 0},
{groupPoint: '04:00', soldLeads: 0},
{groupPoint: '05:00', soldLeads: 0},
{groupPoint: '06:00', soldLeads: 0},
{groupPoint: '07:00', soldLeads: '4'},
{groupPoint: '07:00', soldLeads: 0},
{groupPoint: '08:00', soldLeads: '1'},
{groupPoint: '08:00', soldLeads: 0},
{groupPoint: '09:00', soldLeads: 0},
{groupPoint: '10:00', soldLeads: 0},
]

My code (I would like to get this using reduce):

 const result = initialData.reduce((acc, categoryItem, idx) => {
        return [
          ...acc,
          ...data
            .map((dataItem, index) => {
              if (categoryItem.groupPoint === dataItem.groupPoint) {
                return {
                  groupPoint: dataItem.groupPoint,
                  ...dataItem,
                };
              }
              if (index === data.length - 1 && !acc[idx]) {
                return { ...categoryItem };
              }
            })
            .filter(Boolean),
        ];
      }, []);

I see that the problem: !acc[idx] (it does not know that there is something in the "acc")

2

Answers


  1. If you want to use .reduce() you can use .find() to compare properties and push the new object to the accumulator.

    const result = initialData.reduce((acc, item) => {
      const foundItem = data.find((dataItem) => dataItem.groupPoint === item.groupPoint);
      acc.push({
        groupPoint: item.groupPoint,
        soldLeads: foundItem ? foundItem.soldLeads : 0
      });
      return acc;
    }, []);
    

    I would however, map over the array and use .find to compare the properties of the two objects.

    const result = initialData.map((item) => {
      const foundItem = data.find((dataItem) => dataItem.groupPoint === item.groupPoint);
      return {
        groupPoint: item.groupPoint,
        soldLeads: foundItem ? foundItem.soldLeads : 0
      };
    });
    
    Login or Signup to reply.
  2. You can use Array#map to create the new array and Array#find to search for a matching element from the other array.

    const initialData=[{groupPoint:"00:00",soldLeads:0},{groupPoint:"01:00",soldLeads:0},{groupPoint:"02:00",soldLeads:0},{groupPoint:"03:00",soldLeads:0},{groupPoint:"04:00",soldLeads:0},{groupPoint:"05:00",soldLeads:0},{groupPoint:"06:00",soldLeads:0},{groupPoint:"07:00",soldLeads:0},{groupPoint:"08:00",soldLeads:0},{groupPoint:"09:00",soldLeads:0},{groupPoint:"10:00",soldLeads:0},],data=[{groupPoint:"03:00",soldLeads:"4"},{groupPoint:"04:00",soldLeads:"1"},{groupPoint:"07:00",soldLeads:"1"}];
    const res = initialData.map(x => data.find(y => y.groupPoint === x.groupPoint) ?? x);
    // if a shallow copy is desired, use spread syntax:
    // ({...data.find(y => y.groupPoint === x.groupPoint) ?? x})
    console.log(res);

    To avoid quadratic runtime, you can first create an object that maps each groupPoint from the second array to its corresponding object. Then apply Array#map after that, for a total time complexity of O(n).

    const initialData=[{groupPoint:"00:00",soldLeads:0},{groupPoint:"01:00",soldLeads:0},{groupPoint:"02:00",soldLeads:0},{groupPoint:"03:00",soldLeads:0},{groupPoint:"04:00",soldLeads:0},{groupPoint:"05:00",soldLeads:0},{groupPoint:"06:00",soldLeads:0},{groupPoint:"07:00",soldLeads:0},{groupPoint:"08:00",soldLeads:0},{groupPoint:"09:00",soldLeads:0},{groupPoint:"10:00",soldLeads:0},],data=[{groupPoint:"03:00",soldLeads:"4"},{groupPoint:"04:00",soldLeads:"1"},{groupPoint:"07:00",soldLeads:"1"}];
    const lookup = Object.fromEntries(data.map(o => [o.groupPoint, o]));
    const res = initialData.map(o => lookup[o.groupPoint] ?? o);
    console.log(res);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search