0

I am trying to find all the objects that contain the same key value pair and create a new array of objects with the duplicate objects with the number of times they were found.

For example, if two objects contain the key value pair, type: 'apples', an output object should represent the value, in this case, 'apples', and the number of times it appeared, twice.

Here is an example:

const inventory = [
  { type: 'apples' },
  { type: 'bananas' },
  { type: 'apples' },
  { type: 'orange' },
  { type: 'orange' },
  { type: 'orange' },
];

const duplicates = inventory.reduce((acc, item) => {
  let newItem = acc.find((i) => i.type === item.type); // check if an item with the current type exists
  
  if (newItem) {
    // create a new object w/ new shape
    item.name = item.type;
    item.count = 1;
    acc.push(item);
  } else {
    // object exists -> update count
    item.count += 1;
  }
  return acc;
}, []);

console.log(duplicates);


// Successful output array
// duplicates = [
//   {
//     name:'apples',
//     count:2
//   },
//   {
//     name:'bananas',
//     count:1
//   }
//   {
//     name:'oranges',
//     count:3
//   }
// ]

Tyler Morales
  • 1,440
  • 2
  • 19
  • 56
  • also [Increase count property on object if duplicate value exists in an array](https://stackoverflow.com/questions/70429788/increase-count-property-on-object-if-duplicate-value-exists-in-an-array) and [Counting duplicates in object array and storing the count as a new object have error !!! react js](https://stackoverflow.com/questions/72326965/counting-duplicates-in-object-array-and-storing-the-count-as-a-new-object-have-e) and [Count duplicate value from array into array...](https://stackoverflow.com/questions/58425001/count-duplicate-value-from-array-into-array-of-object-in-javascript) – pilchard Mar 09 '23 at 21:51
  • as for updating object shape [Changing the key name in an array of objects?](https://stackoverflow.com/questions/6809659/changing-the-key-name-in-an-array-of-objects) and [How to change property name in array of objects in Javascript?](https://stackoverflow.com/questions/70495543/how-to-change-property-name-in-array-of-objects-in-javascript) – pilchard Mar 09 '23 at 21:54
  • The difference between plural "apples" and singular "orange" needs to be normalized before I can answer this question. ;) – Wyck Mar 09 '23 at 22:07

4 Answers4

0

You can also do:

const inventory = [{"type":"apples"},{"type":"bananas"},{"type":"apples"},{"type":"orange"},{"type":"orange"},{"type":"orange"}]

console.log(Object.values(inventory.reduce((a,{type:name})=>
  ((a[name]??={name, count:0}).count++, a), {})))
Andrew Parks
  • 6,358
  • 2
  • 12
  • 27
0

The approach you have taken to find duplicates and count them in the array of objects is close, but there are some issues with the implementation.

  1. In the if block, when a new object with the same type as the current item is found, a new object is created with the properties name and count. This will result in adding an object with the same properties as the original object, except for the additional name and count properties. Instead, you should modify the existing newItem object and increment the count property.

  2. In the else block, you are trying to increment the count property of the original object, but you are using the item reference instead of the newItem reference. This will not update the existing object as intended.

Here's a modified version of your code that addresses these issues:

  const inventory = [
  { type: 'apples' },
  { type: 'bananas' },
  { type: 'apples' },
  { type: 'orange' },
  { type: 'orange' },
  { type: 'orange' },
];

const duplicates = inventory.reduce((acc, item) => {
  let newItem = acc.find((i) => i.type === item.type);
  
  if (newItem) {
    newItem.count += 1;
  } else {
    acc.push({ type: item.type, count: 1 });
  }
  
  return acc;
}, []);

console.log(duplicates);
Abid Real
  • 1
  • 1
0
const inventory = [
  { type: 'apples' },
  { type: 'bananas' },
  { type: 'apples' },
  { type: 'orange' },
  { type: 'orange' },
  { type: 'orange' },
];

const duplicates = inventory.reduce((acc, item) => {
  let newItem = acc.find((i) => i.type === item.type); // check if an item with the current type exists
  //Use !newItem, because if you don't find a object - you don't add it in array
  if (!newItem) {
    // create a new object w/ new shape
    item.name = item.type;
    item.count = 1;
    acc.push(item);
  } else {
    // object exists -> update count
    //You find this object and you need add to finded object
    //item.count += 1;
      newItem.count +=1;
  }
  return acc;
}, []);

console.log(duplicates);
THEMOD
  • 1
  • 1
0

I would suggest giving lodash a try; it makes the code more readable; you can group items in inventory by type then the count is the increment for each occurrence.

const inventory = [
  { type: 'apples' },
  { type: 'bananas' },
  { type: 'apples' },
  { type: 'orange' },
  { type: 'orange' },
  { type: 'orange' },
];

const grouped = _.groupBy(inventory, 'type');

const duplicates = _.map(grouped, group => ({ type: group[0].type, count: group.length }))

console.log(duplicates);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
Deano
  • 11,582
  • 18
  • 69
  • 119
  • 1
    Lodash just seems so overkill in this day and age. This site is an excellent guide on how to break the lodash addiction: https://thescottyjam.github.io/snap.js/#!/nolodash – Adam Specker Mar 09 '23 at 22:06
  • I disagree, Code quality is important, as evidenced by the popularity of Lodash. – Deano Mar 09 '23 at 23:00