0

I have an array of objects, where I'd like to merge some objects if certain data matches. Here is the array:

0: {name: "1", qty: "3", measurement: "Tbsp"}
1: {name: "paprika", qty: "2", measurement: "Tbsp"}
2: {name: "onion", qty: "1", measurement: "cup"}
3: {name: "tomatoes", qty: "16", measurement: "oz"}
4: {name: "tomatoes", qty: "16", measurement: "oz"}

I'd like to match based on the name and measurement keys. I.e. if the name is the same AND the measurement is the same, then combine the object and total the qty, where the resulting object would be:

0: {name: "1", qty: "3", measurement: "Tbsp"}
1: {name: "paprika", qty: "2", measurement: "Tbsp"}
2: {name: "onion", qty: "1", measurement: "cup"}
3: {name: "tomatoes", qty: "32", measurement: "oz"}

I've tried it a few ways using .includes() and .some() but haven't managed with any success yet. Any help appreciated.

0

2 Answers 2

1

This is a good use case for the array reduce method. The following can be used to determine if our accumulator already has the desired item. If so, add the quantity. If not, push the item onto the accumulator array.

const items = [
  {name: "1", qty: 3, measurement: "Tbsp"}, 
  {name: "paprika", qty: 2, measurement: "Tbsp"},
  {name: "onion", qty: 1, measurement: "cup"},
  {name: "tomatoes", qty: 16, measurement: "oz"},
  {name: "tomatoes", qty: 16, measurement: "oz"}
];

const combined = items.reduce((acc, el) => {
  const found = acc.find(item => item.name === el.name && item.measurement === el.measurement);
  if (found) {
    found.qty += el.qty;
  } else {
    acc.push(el);
  }
  return acc;
}, []);

console.log(combined);

Sign up to request clarification or add additional context in comments.

1 Comment

This solved my problem excellently. Thank you so much!
0

Approach using a Map and concatenating the name and measurement to create the unique keys so they look like "tomatoes|oz"

const groupItems = (arr) => {
  const m = new Map;      
  arr.forEach(o => {
      const k = `${o.name}|${o.measurement}`;
      // if the key already exists just add current qty 
      // otherwise set new entry using current object
      m.has(k) ? m.get(k).qty += o.qty : m.set(k, {...o});
  });      
  return [...m.values()];
}

console.log(groupItems(data))
<script>
const data=[{name:"1",qty:3,measurement:"Tbsp"},{name:"paprika",qty:2,measurement:"Tbsp"},{name:"onion",qty:1,measurement:"cup"},{name:"tomatoes",qty:16,measurement:"oz"},{name:"tomatoes",qty:16,measurement:"oz"}];
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.