Search code examples
javascripttypescriptjavascript-objects

JavaScript optimize array of objects


Hi I'm creating an array

this.data = [{
  label: 'Total',
  count: details.request.length,
}, {
  label: 'In-Progress',
  count: details.request.filter((obj) =>
    obj.statusId === 0 ||
    obj.statusId === 1 ||
    obj.statusId === 3 ||
    obj.statusId === 4
      ? obj
      : null,
  ).length,
}, {
  label: 'Success',
  count: details.request.filter(({ statusId }) =>
    statusId === 6 ? statusId : null,
  ).length,
  additionalObj: details.request.filter((obj) =>
    obj.statusId === 6 ? obj : null,
  ),
}, {
  label: 'Failed',
  count: details.request.filter(({ statusId }) =>
    statusId === 2 || statusId === 5 ? statusId : null,
  ).length,
  additionalObj: details.request.filter((obj) =>
    obj.statusId === 2 || obj.statusId === 5 ? obj : null,
  ),
}];

I'm creating the array in the structured I need, but have optimize this, I'm using array filter multiple times while calculating count and also for additionalObj. I'm not sure how can I use filter once for both calculating count and additionalObj. Would be great if someone can help me on optimizing my code.

FYI, this is the details structure:

details = {
  request: []
}

Solution

  • Is there any specific reason you are using filter instead of a for loop?

    The code can be written as the following, which uses only a single loop:

    function partition(details: { request: { statusId: number }[] }) {
        let inProgressCount = 0;
    
        let successCount = 0;
        const successAdditionalObj: { statusId: number }[] = [];
    
        let failedCount = 0;
        const failedAdditionalObj: { statusId: number }[] = [];
    
        details.request.forEach((req) => {
            switch (req.statusId) {
                case 0:
                case 1:
                case 3:
                case 4:
                    inProgressCount += 1;
                    break;
    
                case 6:
                    successCount += 1;
                    successAdditionalObj.push(req);
                    break;
    
                case 2:
                case 5:
                    failedCount += 1;
                    failedAdditionalObj.push(req);
                    break;
    
                default:
                    break;
            }
        });
    
        return [
            {
                label: "Total",
                count: details.request.length || 0,
            },
            {
                label: "In-Progress",
                count: inProgressCount,
            },
            {
                label: "Success",
                count: successCount,
                additionalObj: successAdditionalObj,
            },
            {
                label: "Failed",
                count: failedCount,
                additionalObj: failedAdditionalObj,
            },
        ];
    }
    
    this.data = partition(dataToBeTransformed);