Let's try to decompose this. We'll start by writing a generic utility function which we will call combine, which combines properties on objects using a function specified for each property in a hash called combiners:
function combine(array, combiners) {
const result = {};
for (prop of Object.keys(combiners)) {
result[prop] = combiners[prop](...array.map(elt => elt[prop]));
}
return result;
}
Example of using this:
combine(
[{a: 1, b: 10}, {a: 42, b: 80}],
{a: sum, b: Math.max}
)
which will result in
{a: 43, b: 80}
Of course, to make this work, we'll have to define sum:
function sum(...vals) { return vals.reduce(add); }
where add is just
function add(a, b) { return a + b; }
Next, we will group the input by the Emiten_ID property. You could use Underscore's _.groupBy for this, or write your own (see below).
const groups = _.groupBy(myArray, 'Emiten_ID`);
This will result in something looking like
{ SMBR: [
{ Emiten_ID: 'SMBR', "Lot": 500, "Price": 2500},
{ Emiten_ID: 'SMBR', "Lot": 300, "Price": 2200}
],
ELSA: [
]
}
After doing this prep work, it is pretty easy to get the result, by just mapping each value in groups using our combine utility:
const Result = Object.keys(groups).map(key =>
combine(
groups[key],
{
Emiten_ID: identity,
Lot: sum,
Price: Math.max}));
where identity is just
function identity(id) { return id; }
If you'd prefer to abstract away the notion inside combine of mapping object properties, you could use some utility from Underscore again, or write it yourself:
function mapObject(obj, fn) {
const result = {};
for (prop of obj) result[prop] = fn(obj[prop], prop);
return result;
}
Example of using this:
mapObject({a: 2, b: 3}, x => x * x)
// yields {a: 4, b: 9}
Now you can write combine a bit more simply, as
function combine(array, combiners) {
return mapObject(combiners, function(combiner, prop) {
return combiner(...array.map(elt => elt[prop]));
};
}
In case you don't want to use Underscore's _.groupBy, here's a home grown version:
function groupBy(array, prop) {
var result = {};
array.forEach(elt => (result[elt[prop]] = result[elt[prop]] || []).push(elt));
return result;
}