0

I am having one report array of objects which is used to show report data on the dashboard as below,

    report = [
              {id: "id01", code: "C001", name: "apples", type: "fruits", intime:[], quantity:[]},
              {id: "id01", code: "C001", name: "grapes", type: "fruits", intime:[], quantity:[]},
              {id: "id01", code: "C002", name: "apples", type: "fruits", intime:[], quantity:[]},
              {id: "id01", code: "C002", name: "grapes", type: "fruits", intime:[], quantity:[]}
             ]

And below array as input,

record = [
    {code: "C001",
    records :[{intime: "15:32:12", apples: "30", grapes: "80"},
            {intime: "15:32:13", apples: "34", grapes: "50"}]
    },  
    {code: "C002",
    records :[{intime: "15:32:12", apples: "56", grapes: "100"},
            {intime: "15:32:13", apples: "75", grapes: "38"}]
    },      
]

I want to put these values to arrays of report array as per matching condition so that report array should look like,

report = [
  {id: "id01", code: "C001", name: "apples", type: "fruits", intime:["15:32:12","15:32:13"], quantity:[30,34]},
  {id: "id01", code: "C001", name: "grapes", type: "fruits", intime:["15:32:12","15:32:13"], quantity:[80,50]},
  {id: "id01", code: "C002", name: "apples", type: "fruits", intime:["15:32:12","15:32:13"], quantity:[56,75]},
  {id: "id01", code: "C002", name: "grapes", type: "fruits", intime:["15:32:12","15:32:13"], quantity:[100,38]}
]

I think , this can be achieved through array filter method in loop but that method does not seems efficient when record array is big in size. Please suggest me some better and efficient way to put values in such way.

1
  • Create an object that uses code as the key and the values are arrays of elements of report. Commented Feb 18, 2020 at 17:54

3 Answers 3

2
const finalReport = report.map(rep => {
  let obj = { ...rep };

  const recordFoundByCode = record.find(rec => rec.code === obj.code);

  if (recordFoundByCode) {
    recordFoundByCode.records.forEach(item => {
      obj.intime.push(item.intime);
      obj.quantity.push(item[obj.name]);
    });
  }

  return obj;
});

console.log(finalReport) // <== your desired array
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks @Sushmit. This method also very efficient. I tested for 250K pre existing array records and it inserted new record in 4 milliseconds.
Awesome! Happy to help :)
HI @Sushmit , just a small concern. It is failing with error "TypeError: Cannot read property 'record' of undefined" when in record , entry for code: "C002" is absent. in my case , i may or may not get the values for all codes in one go. please suggest how to handle this case.
you can wrap the forEach block in if (recordFoundByCode) {} condition.
0

Create an object that uses code as the keys to find all the related report objects. Then use nested loops to insert the times in all the intime arrays.

var report = [
  {id: "id01", code: "C001", name: "apples", type: "fruits", intime:[], quantity:[]},
  {id: "id01", code: "C001", name: "grapes", type: "fruits", intime:[], quantity:[]},
  {id: "id01", code: "C002", name: "apples", type: "fruits", intime:[], quantity:[]},
  {id: "id01", code: "C002", name: "grapes", type: "fruits", intime:[], quantity:[]}
];

record = [
    {code: "C001",
    records :[{intime: "15:32:12", apples: "30", grapes: "80"},
            {intime: "15:32:13", apples: "34", grapes: "50"}]
    },  
    {code: "C002",
    records :[{intime: "15:32:12", apples: "56", grapes: "100"},
            {intime: "15:32:13", apples: "75", grapes: "38"}]
    },      
];
             
var report_by_code = report.reduce((o, r) => {
    if (o[r.code]) {
        o[r.code].push(r);
    } else {
        o[r.code] = [r];
    }
    return o;
}, {});
record.forEach(({code, records}) => records.forEach(({intime}) =>  
    report_by_code[code].forEach(r => r.intime.push(intime))));

console.log(report);

Comments

0
_.each(report, rep => {
    let code = rep.code;
    let name = rep.name;
    _.each(record, rec => {
        if(rec.code === code) {
            let recs = rec.records;
            _.each(recs, re => {
                rep.intime.push(re.intime);
                rep.quantity.push(re[name]);
            });
        }
    });
});

You could utilize the 'underscore' module for JavaScript in this scenario. First I start with an each loop that iterates over each object in the report array. Then we can store the code and the name keys associated with that object. We can then iterate over each record and if the codes are equal we can iterate over that particular object. We can then iterate over each of the records and store the intime and then the fruit quantity based on the fruit name associated with the report object that we are currently iterating over. We then push those values to the intime and quantity arrays associated with that report object.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.