2

i have the following two array objects

const plan = [
              {Item_ID : 01, Date:"2020-04-01", Items:"10"}, 
              {Item_ID : 02, Date:"2020-04-01", Items:"20"},
              {Item_ID : 03, Date:"2020-04-02", Items:"40"},
              {Item_ID : 05, Date:"2020-04-03", Items:"10"},
             ];

const actual = [{Date:"2020-04-01", Actual_Items:"15"}, 
                {Date:"2020-04-02", Actual_Items:"40"}, 
                {Date:"2020-04-05", Actual_Items:"50"},                    
               ];

these two array shows planned sales and actual sales, based on these two array im trying to create the below array

 const plan = [
              {Item_ID : 01, Date:"2020-04-01", Items:"10", Actual_Items:"15"}, 
              {Item_ID : 02, Date:"2020-04-01", Items:"20", Actual_Items:"15"},
              {Item_ID : 03, Date:"2020-04-02", Items:"40", Actual_Items:"40"},
              {Item_ID : 05, Date:"2020-04-03", Items:"10", Actual_Items:"0"},
              {Item_ID : null, Date:"2020-04-04", Items:"0", Actual_Items:"0"},
              {Item_ID : null, Date:"2020-04-05", Items:"0", Actual_Items:"50"},
             ];

so based on the planned array if these is actual sales done for that day we show otherwise show 0. if nothing was planned but sales was done then Item_ID will be null Items will be null but Actual_Items need to show the number of sales.

I've created bellow map function maybe completely wrong logic and i was not able to continue future, any idea how to create this final array

let op = plan.map((e,i)=>{
      let temp = actual.find(element=> element.Date === e.Date)
      if(temp.Actual_Items) {
        e.Actual_Items= temp.Actual_Items;
      }
      return e;
    })
    console.log(op);
Elite user
  • 101
  • 1
  • 10
  • 1
    Does this answer your question? [Merge two array of objects based on a key](https://stackoverflow.com/questions/46849286/merge-two-array-of-objects-based-on-a-key) – Harun Yilmaz Mar 31 '20 at 09:02
  • 2
    your desired outcome doesn't seem to match the input you are giving (eg: there is no 2020-04-04 in your inputs). Why not create a object (Map) with date as key and the array item as a value for both arrays, and then combine the items like that (less need to lookup). Also, your map mutates the iterated value, maybe you want to return a new item instead, so you are not mutating the original array? – Icepickle Mar 31 '20 at 09:02
  • You're making a "union" join so you can't loop through one otherwise you'll miss the (where ID=null in the result). You need to loop a "3rd party" - in this case it looks like "date" is what you want to "join" on - so loop through each unique date from both sets and retrieve the data from either based on date. I'm not sure your end result is that useful as you have multiple records with the same "key" (ID or date) – freedomn-m Mar 31 '20 at 09:13

2 Answers2

2

You can join your two array like this:

let op = plan.concat(actual);

or

let op = [...plan, ...actual];

But before you might want to iterate over "actual" to modify the values "Item_ID" and "Items".

Solution look like:

const plan = [
              {Item_ID : 01, Date:"2020-04-01", Items:"10"}, 
              {Item_ID : 02, Date:"2020-04-01", Items:"20"},
              {Item_ID : 03, Date:"2020-04-02", Items:"40"},
              {Item_ID : 05, Date:"2020-04-03", Items:"10"},
             ];

const actual = [{Date:"2020-04-01", Actual_Items:"15"}, 
                {Date:"2020-04-02", Actual_Items:"40"}, 
                {Date:"2020-04-05", Actual_Items:"50"},                    
               ];

actual.forEach(function(part, index) {
  part.Items = "0";
  part.Item_ID = null;
  this[index] = part;
}, actual);

let op = plan.concat(actual);

console.log(op);
1

You could use an object for same date, collect the plan values and then add actual as well.

You may finally add missing dates to the result array.

const
    plan = [{ Item_ID: "01", Date: "2020-04-01", Items: "10" }, { Item_ID: "02", Date: "2020-04-01", Items: "20" }, { Item_ID: "03", Date: "2020-04-02", Items: "40" }, { Item_ID: "05", Date: "2020-04-03", Items: "10" }],
    actual = [{ Date: "2020-04-01", Actual_Items: "15" }, { Date: "2020-04-02", Actual_Items: "40" }, { Date: "2020-04-05", Actual_Items: "50" }],
    pattern = { Item_ID: null, Date: null, Items: "0", Actual_Items: "0" },
    result = Object
        .values(actual.reduce(
            (r, o) => {
                r[o.Date] = r[o.Date] || [{ ...pattern }];
                r[o.Date].forEach(p => Object.assign(p, o));
                return r;
            },
            plan.reduce((r, o) => {
                (r[o.Date] = r[o.Date] || []).push({ ...pattern, ...o });
                return r;
            }, {})
        ))
        .flat()
        .reduce((r, o, i, { [i - 1]: prev }) => {
            if (!r) return [o];
            var p = new Date(prev.Date).getTime() + 1000 * 60 * 60 * 24;
            while (p < new Date(o.Date).getTime()) {
                let d = new Date;
                d.setTime(p);
                r.push({ ...pattern, Date: d.toISOString().slice(0, 10) });
                p += 1000 * 60 * 60 * 24;
            }
            r.push(o);
            return r;
        }, undefined);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392