Reputation: 936
I have the array of objects:
[
{ pair_id: 1, exchange_pair_id: 183 },
{ pair_id: 1, exchange_pair_id: 2},
...
]
I want to rebuild this array as
[
{ pair_id: 1, exchange_pair_id: [183, 2] },
...
]
Here is the code I have written (the code which brings me closest to the desired result anyway):
var array = [];
rows.forEach(function(row) {
var obj = {};
obj.pair_id = [row.pair_id];
obj.exchange_pair_id = [row.exchange_pair_id]
array.push(obj);
});
Which results in:
[
{ pair_id: 1, exchange_pair_id: [183] },
{ pair_id: 1, exchange_pair_id: [2] },
...
]
This seems like a very simple problem with a simple solution, but I've been wracking my brains and can't figured it out.
Upvotes: 0
Views: 2154
Reputation: 3801
You're close, you just need to check if there's previous results. Using a map is more time efficient than looking through the list with something like find
every time you see an item.
var results = new Map();
rows.forEach(function(row) {
previous_result = results.get(row.pair_id)
if (previous_result != null) {
previous_result.exchange_pair_id.push(row.exchange_pair_id);
} else {
var obj = {};
obj.pair_id = row.pair_id;
obj.exchange_pair_id = [row.exchange_pair_id]
results.set(row.pair_id, obj);
}
});
Array.from(results.values())
Upvotes: 0
Reputation: 13346
Try this:
var arr1 = [
{ pair_id: 1, exchange_pair_id: 183 },
{ pair_id: 1, exchange_pair_id: 2},
];
var arr2 = [];
arr1.forEach(el => {
var obj = arr2.find(it => it.pair_id === el.pair_id);
if (!obj) {
el.exchange_pair_id = [el.exchange_pair_id];
arr2.push(el);
} else {
obj.exchange_pair_id.push(el.exchange_pair_id);
}
});
console.log(arr2);
Upvotes: 0
Reputation: 68635
Try this solution. I iterate over the array by Array#forEach and try to find an element in the groupedArray
by pair_id
using Array#find function. If the element is found I push the exchange_pair_id
into the array of that element. If not I create a new item in the array according to the item's values.
const array = [
{ pair_id: 1, exchange_pair_id: 183 },
{ pair_id: 1, exchange_pair_id: 2},
{ pair_id: 2, exchange_pair_id: 7},
{ pair_id: 3, exchange_pair_id: 988},
{ pair_id: 2, exchange_pair_id: 8},
{ pair_id: 3, exchange_pair_id: 98}
];
const groupedArray = [];
array.forEach(item => {
const found = groupedArray.find(x => x.pair_id === item.pair_id);
if(found) {
found.exchange_pair_id.push(item.exchange_pair_id);
} else {
groupedArray.push({ pair_id: item.pair_id, exchange_pair_id: [item.exchange_pair_id]});
}
});
console.log(groupedArray);
Upvotes: 4
Reputation: 5188
What you're trying to do is aggregation or reduction, so I'd use Array.reduce()
here. Take each element in turn and build up a new set of elements, like this:
const rows = [
{ pair_id: 1, exchange_pair_id: 183 },
{ pair_id: 1, exchange_pair_id: 2},
{ pair_id: 4, exchange_pair_id: 6}
];
const result = rows.reduce( function( aggregate, nextElement ) {
const pair_id = nextElement.pair_id;
//create a new row in the aggregate if one doesn't exist
let aggregatedRow = aggregate.find( r => r.pair_id === pair_id );
if ( !aggregatedRow ) {
aggregatedRow = { pair_id, exchange_pair_id: [] };
aggregate.push( aggregatedRow );
}
//add the new exchange pair id to the aggregate row
aggregatedRow.exchange_pair_id.push( nextElement.exchange_pair_id );
return aggregate;
}, []); //start with an empty array
console.log( result );
Upvotes: 0
Reputation: 386550
You could take a hash table for same pair_id
.
var array = [{ pair_id: 1, exchange_pair_id: 183 }, { pair_id: 1, exchange_pair_id: 2}],
hash = Object.create(null),
result = array.reduce(function (r, o) {
if (!hash[o.pair_id]) {
hash[o.pair_id] = [];
r.push({ pair_id: o.pair_id, exchange_pair_id: hash[o.pair_id] });
}
hash[o.pair_id].push(o.exchange_pair_id);
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0