0

I have an array of objects like the following:

[
    {
        'Product': 'P1',
        'Price': 150,
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 100,
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 200,
        'Location': 2,
    },
    {
        'Product': 'P2',
        'Price': 10,
        'Location': 1,
    },
    {
        'Product': 'P2',
        'Price': 130,
        'Location': 1,
    },
    {
        'Product': 'P3',
        'Price': 40,
        'Location': 1,
    }
]

I need to add up all the prices for objects with the same product and same location. For the example above the result would be:

[
   {
        'Product': 'P1',
        'Price': 250, // price is the sum of both similar in location and product
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 200,
        'Location': 2, // same product but different location
    },
    {
        'Product': 'P2',
        'Price': 140, //sum of same
        'Location': 1, 
    },
    {
        'Product': 'P3',
        'Price': 40,
        'Location': 1,
    },
]

I have searched several similar issues, but those were dealing with only one key to check for, I have different keys (product and location - may be more than 2 in the future) to identify as different.

3 Answers 3

2

const input = [
    {
        'Product': 'P1',
        'Price': 150,
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 100,
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 200,
        'Location': 2,
    },
    {
        'Product': 'P2',
        'Price': 10,
        'Location': 1,
    },
    {
        'Product': 'P2',
        'Price': 130,
        'Location': 1,
    },
    {
        'Product': 'P3',
        'Price': 40,
        'Location': 1,
    }
]

const output = []
input.forEach(item => {
  const index = output.findIndex(o => o.Product === item.Product && o.Location === item.Location);
  if (index === -1) {
    output.push(item);
  } else {
    output[index].Price += item.Price;
  }
});
console.log(output);


Without arrow function

input.forEach(function(item) {
  const index = output.findIndex(function(o) { return o.Product === item.Product && o.Location === item.Location});
  if (index === -1) {
    output.push(item);
  } else {
    output[index].Price += item.Price;
  }
});
Sign up to request clarification or add additional context in comments.

Comments

2

You can use reduce() to do that,

obj = [
   {
        'Product': 'P1',
        'Price': 250, // price is the sum of both similar in location and product
        'Location': 1,
    },
    {
        'Product': 'P1',
        'Price': 200,
        'Location': 2, // same product but different location
    },
    {
        'Product': 'P2',
        'Price': 140, //sum of same
        'Location': 1, 
    },
    {
        'Product': 'P3',
        'Price': 40,
        'Location': 1,
    },
]

res = obj.reduce((prev, curr) => {
  index = prev.findIndex(item => item.Product=== curr.Product && item.Location === curr.Location);
  if(index > -1) {
    prev[index].Price += curr.Price;
  } else {
    prev.push(curr);
  }
  return prev;
}, []);

console.log(res);

Comments

0

Modifying @William's answer (Accepted) for my use case as it was to be run on the platform which was not supporting ES6 features (findIndex and arrow function), this can be done without findIndex as below;

var input = [{
    'Product': 'P1',
    'Price': 150,
    'Location': 1,
  },
  {
    'Product': 'P1',
    'Price': 100,
    'Location': 1,
  },
  {
    'Product': 'P1',
    'Price': 200,
    'Location': 2,
  },
  {
    'Product': 'P2',
    'Price': 10,
    'Location': 1,
  },
  {
    'Product': 'P2',
    'Price': 130,
    'Location': 1,
  },
  {
    'Product': 'P3',
    'Price': 40,
    'Location': 1,
  }
]

var output = []
input.forEach(function(item) {
  var index = output.indexOf(output.filter(function(o) {
    return o.Product === item.Product && o.Location === item.Location
  })[0]); // note the [0] index here
  if (index === -1) {
    output.push(item);
  } else {
    output[index].Price += item.Price;
  }
});
console.log(output);

1 Comment

there is a button that reads "Tidy" inside the snippet editor that formats your code - please use that after you finish editing your snippet. (it's right below "save and insert post" button)

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.