simon blanco
simon blanco

Reputation: 148

How can I filter this array of objects?

I am trying that in this array there are only objects that do not have the duplicate _id property and also have the amount property with the largest number that there is between the duplicate objects.

const array = [ 
                { _id: '12398gsbya', amount: 1 },
                { _id: '12398gsbya', amount: 2 },
                { _id: '12398gsbya', amount: 3 },
                { _id: '12398gsbya', amount: 1 },
                { _id: '12398gsbya', amount: 2 },
                { _id: '12398gsbya', amount: 3 },
                { _id: 'f9h8gasd90', amount: 1 },
                { _id: 'f9h8gasd90', amount: 2 },
                { _id: '12398gsbya', amount: 1 },
                { _id: '12398gsbya', amount: 2 },
                { _id: '12398gsbya', amount: 3 },
                { _id: 'f9h8gasd90', amount: 1 },
                { _id: 'f9h8gasd90', amount: 2 },
                { _id: 'f9h8afgh80', amount: 1 } 
              ];

The result I am looking for would be like this:

const array = [ 
                { _id: '12398gsbya', amount: 3 },
                { _id: 'f9h8gasd90', amount: 2 },
                { _id: 'f9h8afgh80', amount: 1 } 
              ];

This is what I tried but I can't get it to return the duplicates with the highest amount property.

  var hash = {};
  let arrayWithoutDuplicates = arrayWithDuplicates.filter(function(currentValue){
    console.log(currentValue)
    var exists = !hash[currentValue._id]
    hash[currentValue._id] = true;
    return exists;
  })

  console.log(arrayWithoutDuplicates)

  [
   { _id: '12398gsbya', amount: 1 },
   { _id: 'f9h8gasd90', amount: 1 },
   { _id: 'f9h8afgh80', amount: 1 }
  ]

Upvotes: 0

Views: 42

Answers (2)

kyun
kyun

Reputation: 10264

I think there are many ways to solve it but this also does work.

const arr = [{
    _id: '12398gsbya',
    amount: 1
  },
  {
    _id: '12398gsbya',
    amount: 2
  },
  {
    _id: '12398gsbya',
    amount: 3
  },
  {
    _id: '12398gsbya',
    amount: 1
  },
  {
    _id: '12398gsbya',
    amount: 2
  },
  {
    _id: '12398gsbya',
    amount: 3
  },
  {
    _id: 'f9h8gasd90',
    amount: 1
  },
  {
    _id: 'f9h8gasd90',
    amount: 2
  },
  {
    _id: '12398gsbya',
    amount: 1
  },
  {
    _id: '12398gsbya',
    amount: 2
  },
  {
    _id: '12398gsbya',
    amount: 3
  },
  {
    _id: 'f9h8gasd90',
    amount: 1
  },
  {
    _id: 'f9h8gasd90',
    amount: 2
  },
  {
    _id: 'f9h8afgh80',
    amount: 1
  }
];
const res = arr.reduce((acc, cur) => {
  if (acc?.[cur._id] < cur.amount) {
    acc[cur._id] = cur.amount;
  } else {
    acc[cur._id] = cur.amount;
  }
  return acc;
}, {});
const out = Object.entries(res).map(([_id, amount]) => {
  return {
    _id,
    amount
  }
});
console.log(out);

Upvotes: 1

DecPK
DecPK

Reputation: 25408

You could use reduce method;

const array = [
  { _id: "12398gsbya", amount: 1 },
  { _id: "12398gsbya", amount: 2 },
  { _id: "12398gsbya", amount: 3 },
  { _id: "12398gsbya", amount: 1 },
  { _id: "12398gsbya", amount: 2 },
  { _id: "12398gsbya", amount: 3 },
  { _id: "f9h8gasd90", amount: 1 },
  { _id: "f9h8gasd90", amount: 2 },
  { _id: "12398gsbya", amount: 1 },
  { _id: "12398gsbya", amount: 2 },
  { _id: "12398gsbya", amount: 3 },
  { _id: "f9h8gasd90", amount: 1 },
  { _id: "f9h8gasd90", amount: 2 },
  { _id: "f9h8afgh80", amount: 1 },
];

const result = array.reduce((acc, curr) => {
  const element = acc.find((el) => el._id === curr._id);
  if (!element) {
    acc.push(curr);
  } else {
    element.amount =
      curr.amount > element.amount ? curr.amount : element.amount;
  }
  return acc;
}, []);

console.log(result);

Upvotes: 2

Related Questions