Sarmad Shah
Sarmad Shah

Reputation: 3805

Mutate or Make a new Array by replacing a value

I have two arrays (and the length can be in 1000s):

I want my array to replace status to the status of array 2. Here is the output example:

[{
value: 123,
status: 'demo',
type: '...'
},
{value: 2335,
 status: 'demo2',
 type: 'xxx'
}]

As we can see it needs to get the status from another array and replace it. What are the most possible efficient solutions for this? As this array can be very large. I don't know a good approach to solve this problem. Length and sort order can be different, I need to replace array1's status by the array2's status, By linking Array1's status and Array2's id

My actual Data

[
   {
    "id": "55",
    "status": "2",
    "type": "COD",
     "value": "5038.2",
   },
 {
   "id": "56",
   "status": "2",
   "type": "COD",
    "value": "5398.2",
  },
   {
    "id": "57",
    "status": "2",
    "type": "COD",
    "value": "10798.2",
  }

 ]

Array 2

[
   {
     "id": "1",
    "status": "Awaiting Confirmation",
   },
   {
    "id": "2",
    "status": "Confirmed",
   },
   {
    "id": "3",
     "status": "Awaiting Shipment",
  },
  {
     "id": "4",
    "status": "Awaiting Pickup",
   },
   {
    "id": "5",
    "status": "Shipped",
   },
 {
   "id": "6",
    "status": "Delivered",
   },
   {
     "id": "7",
    "status": "Cancelled",
  },
  {
   "id": "8",
    "status": "Refund Requested",
   },
   {
     "id": "9",
     "status": "Refunded",
   }

Things i have tried...I have used lodash and a for loop to achieve this

const output = [];
      for (let i = 0; i < array1.length; i++) {
        const statuscode = array1[i].status;
        const result = _.find(array2, { id: statuscode });
        output.push({
          value: array1[i].value,
          status: result.status,
          type: array1[i].type
        });
      }
      console.log(output);

Upvotes: 2

Views: 240

Answers (2)

CertainPerformance
CertainPerformance

Reputation: 370679

For high performance, transform one of the arrays to a Map first. Map lookups are very efficient:

const input1 = [{
    value: 123,
    status: 1,
    type: 'COD',
  },
  {
    value: 2335,
    status: 2,
    type: 'COD',
  },
  {
    value: 222,
    status: 3,
    type: 'COD',
  }
];
const input2 = [{
    id: 1,
    status: 'demo'
  },
  {
    id: 2,
    status: 'demo2'
  }, {
    id: 3,
    status: 'demo3'
  }
];
const map2 = new Map(Object.values(input2).map(({ id, status }) => [id, status]));
const output = input1.map(({ status, ...rest }) => {
  const otherStatus = map2.get(status);
  return { ...rest, status: otherStatus };
});
console.log(output);

Code readability generally matters more than speed, but if you wanted, you could transform the .map transformation into a for loop as well:

const input1 = [{
    value: 123,
    status: 1
  },
  {
    value: 2335,
    status: 2
  },
  {
    value: 222,
    status: 3
  }
];
const input2 = [{
    id: 1,
    status: 'demo'
  },
  {
    id: 2,
    status: 'demo2'
  }, {
    id: 3,
    status: 'demo3'
  }
];
const map1 = new Map(Object.values(input1).map(({ value, status }) => [status, value]));
const output = [];
for (let i = 0; i < input2.length; i++) {
  const { id, status } = input2[i];
  output.push({ value: map1.get(id), status });
}
console.log(output);

Upvotes: 1

bugs
bugs

Reputation: 15313

A simple for loop would do:

for (let i = 0; i < array1.length; i++) {
  array1[i].status = array2[i].status;
}

This of course assumes that the length and the order of the two arrays is the same.

EDIT

Alternative solution using Array.prototype.find and taking into account different lengths and orders.

for (let i = 0; i < array1.length; i++) {
  const buffer = array1[i];
  buffer.status = array2.find(x => x.id === buffer.status).status;
}

Also, I would highly recommend giving priority to readability over premature optimisation

Upvotes: 1

Related Questions