2

I have the following array of objects:

[{"id":0,"name":"Katy","age":22},
{"id":2,"name":"Lucy","age":12},
{"id":1,"name":"Jenna","age":45},
{"id":3,"name":"Ellie","age":34}]

I need to add another key into the objects (PaymentCategory) where whichever object has the lowest ID is added the key with value "Cash", the one with highest ID "Card", and everything in between "Cheque"; the array also must then be sorted by ID.

Hence required output would be:

[{"PaymentCategory":"Cash","id":0,"name":"Katy","age":22},
{"Payment Category":"Cheque","id":1,"name":"Jenna","age":45},
{"Payment Category":"Cheque","id":2,"name":"Lucy","age":12},
{"Payment Category":"Card","id":3,"name":"Ellie","age":34}]

How can we achieve this result in the most efficient way, i.e. fewest number of iterations, highest performance?

Here's what I tried:

const min = array.reduce((prev,curr)=> prev.id<curr.id?prev:curr)
  const max = array.reduce((prev,curr)=> prev.id>curr.id?prev:curr)
  min.PaymentCategory = "Cash"
  max.PaymentCategory = "Credit"
  const result =[min, max]

The problem with this is:

  1. I'm looping through it twice, one for max, one for min.
  2. How do I get the "middle" values?
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
Min Yoongi
  • 396
  • 5
  • 16
  • Sorry @Peter Seliger for the late reply and answer acception, I had lost my account access in between, hence couldn't see/accept answers. Thanks Peter Seliger and Ali for taking time for answering this question, I was able to verify the output through code. – Min Yoongi Nov 20 '21 at 16:09

2 Answers2

2

The following provided approach is straightforward and first does sort the items of a shallow array copy ([...sampleData]) in an ascending order ( .sort((a, b) => a.id - b.id) ) of id values.

The final task does map each (sorted) item in a way which creates a shallow copy ({ ...item }) and in addition creates a 'Payment Category' entry where the first item ( idx === 0 ) gets assigned the 'Cash' value, the last item ( (idx === arr.length - 1) ) gets assigned the 'Card' value, and all other get assigned the 'Cheque' value.

The entire approach does not mutate the originally provided data ...

const sampleData = [
  { id: 0, name: "Katy", age: 22 },
  { id: 2, name: "Lucy", age: 12 },
  { id: 1, name: "Jenna", age: 45 },
  { id: 3, name: "Ellie", age: 34 },
];

console.log(
  'mapped `sampleData` items ...',

  [...sampleData]
    .sort((a, b) => a.id - b.id)
    .map((item, idx, arr) => ({
      ...item,
      'Payment Category': ((idx === 0)
        && 'Cash') || ((idx === arr.length - 1)
        && 'Card') || 'Cheque',
    }))
);
console.log('unmutated `sampleData` ...', sampleData);
.as-console-wrapper { min-height: 100%!important; top: 0; }

The above approach in an even more readable way ...

const copyItemAndAugmentPaymentCategory = (item, idx, arr) => ({
  ...item,
  'Payment Category': ((idx === 0)
    && 'Cash') || ((idx === arr.length - 1)
    && 'Card') || 'Cheque',
});
const compareItemIdPrecedenceAscending = (a, b) => a.id - b.id;

console.log(
  [
    { id: 0, name: "Katy", age: 22 },
    { id: 2, name: "Lucy", age: 12 },
    { id: 1, name: "Jenna", age: 45 },
    { id: 3, name: "Ellie", age: 34 },
  ]
  .sort(compareItemIdPrecedenceAscending)
  .map(copyItemAndAugmentPaymentCategory)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
1

you can do like this

const array =[{"id":0,"name":"Katy","age":22},
{"id":2,"name":"Lucy","age":12},
{"id":1,"name":"Jenna","age":45},
{"id":3,"name":"Ellie","age":34}]

const arrayLength= array.length
  
const newA=array.map( (element,index) =>  { if (index===0) return {"PaymentCategory":"Cash", ...element}
else if ( index===arrayLength-1 )return {"PaymentCategory":"Card", ...element}
else return {"PaymentCategory":"Cheque", ...element}})

check map method in arrays to learn more : https://learnjsx.com/category/2/posts/es6-mapFunction

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
Ali
  • 118
  • 1
  • 3