skip to Main Content

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: []
}

2

Answers


  1. 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);
    
    Login or Signup to reply.
  2. Your question is not good, neither your code. But I’m just going to say why you’re code is bad and how to fix it.

    The most critical thing in your code regarding PERFORMANCE is you’re iterating details.request multiple times, while you could do the filtering once.

    Iterating an array or list multiple times for different filters in this way can be avoided by using reduce for your case.

    Here is how you can do it by iterating details.request only once with reduce and create an object that has properties representing the status so you don’t need to store that too:

    this.data = details.request.reduce(
      (previous, currentRequest) => {
        switch (currentRequest.statusId) {
          case 2: // failed
          case 5: // failed
            previous.Failed.push(currentRequest);
            return previous;
          case 6: // success
            previous.Success.push(currentRequest);
            return previous;
          default: // instead of iterating other cases
            previous.InProgress++;
            return previous;
        }
      },
      { Total: details.request.length, InProgress: 0, Success: [], Failed: [] }
    );
    // this.data.Total: number
    // this.data.InProgess: number
    // this.data.Failed: requestItem[]
    // this.data.Success: requestItem[]
    

    and here is how to do it your way in case you need it data to be in that specific shape for an Api:

    
    this.data = details.request.reduce(
      (previous, currentRequest) => {
        switch (currentRequest.statusId) {
          case 2: // failed
          case 5: // failed
            previous[3].count++;
            previous[3].additionalObj.push(currentRequest);
            return previous;
          case 6: // success
             previous[2].count++;
             previous[2].additionalObj.push(currentRequest);
            return previous;
          default: // instead of iterating other cases
            previous[1].count++;
            return previous;
        }
      },
      [
        {
          // i: 0
          label: "Total",
          count: details.request.length,
        },
        {
          // i: 1
          label: "In-Progress",
          count: 0,
        },
        {
          // i: 2
          label: "Success",
          count: 0,
          additionalObj: [],
        },
        {
          // i: 3
          label: "Failed",
          count: 0,
          additionalObj: [],
        },
      ]
    );
    // this.data: [{label:string, count:number},
    //   {label:string, count:number},
    //   {label:string, count:number,additionalObj:requestItem[]},
    //   {label:string, count:number,additionalObj:requestItem[]}]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search