0

Suppose I have an array of object,


    const details = [{
        "error": true,
        "errorDetails": [{
          "Information Missing": true,
          "Alignment Issue": false,
          "Unreadable Invoice": true,
          "Line Item Missing": false,
          "Master Data Not Found": false
        }]
      },
      {
        "error": false,
        "errorDetails": [{
          "Information Missing": false,
          "Alignment Issue": false,
          "Unreadable Invoice": false,
          "Line Item Missing": false,
          "Master Data Not Found": false
        }]
      },
      {
        "error": true,
        "errorDetails": [{
          "Information Missing": true,
          "Alignment Issue": true,
          "Unreadable Invoice": true,
          "Line Item Missing": true,
          "Master Data Not Found": false
        }]
      }
    ]


    var result = details.filter(detail => detail.error == true); //o/p gives only true objects,

    console.log(result)

I want to have a count of "Information Missing", "Alignment Issue", "Unreadable Invoice", "Line Item Missing", "Master Data Not Found" when they are true, like: [{"Information Missing" : Number,"Unreadable Invoice" : Number}]

0

3 Answers 3

1

You could use .reduce and accumulate the object that count number of each error detail

const details = [
  {
    error: true,
    errorDetails: [
      {
        "Information Missing": true,
        "Alignment Issue": false,
        "Unreadable Invoice": true,
        "Line Item Missing": false,
        "Master Data Not Found": false,
      },
    ],
  },
  {
    error: false,
    errorDetails: [
      {
        "Information Missing": false,
        "Alignment Issue": false,
        "Unreadable Invoice": false,
        "Line Item Missing": false,
        "Master Data Not Found": false,
      },
    ],
  },
  {
    error: true,
    errorDetails: [
      {
        "Information Missing": true,
        "Alignment Issue": true,
        "Unreadable Invoice": true,
        "Line Item Missing": true,
        "Master Data Not Found": false,
      },
    ],
  },
];

const res = details
  .flatMap((detail) => detail.errorDetails)
  .reduce(
    (acc, el) => {
      Object.entries(el).forEach(([errorDetail, isTrue]) =>
        Object.assign(acc, {
          [errorDetail]: (acc[errorDetail] || 0) + (isTrue ? 1 : 0),
        })
      );
      return acc;
    },

    {}
  );

console.log(res);

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much for your help. Also could you please tell me after return acc, there is {}, is there any significance or justa typo?
@SivaPradhan it is the initial value of acc (object that count number of each error detail), an empty object, for more, you could check the doc for reduce
1

in order to collect all the data with counters we're wanting a different structre object from an array, in such situations we preferably use Array.reduce()

details.reduce((acc,details)=>{
let errorDetails = details.errorDetails[0];
let keys = Object.keys(errorDetails);
keys.forEach((key)=>{
    if(errorDetails[key] == true){
        if(acc.hasOwnProperty(key)){
            acc[key] += 1; 
        }else{
            acc[key] = 1;
        }
    }
})
return acc;
},{});

the returned object for sample data is

{
  "Information Missing": 2,
  "Unreadable Invoice": 2,
  "Alignment Issue": 1,
  "Line Item Missing": 1
}

Comments

0

It's easy:

const result = {
  'Information Missing': 0,
  'Alignment Issue': 0,
  'Unreadable Invoice': 0,
  'Line Item Missing': 0,
  'Master Data Not Found': 0
}
details
  .filter(x => x.error)
  .forEach(x => {
    x.errorDetails.forEach((err) => {
      Object.keys(result).forEach(key => {
        result[key] += err[key] === true ? 1 : 0
      })
    })
  })

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.