0

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.

2
  • 1
    All you do in obj.exchange_pair_id = [row.exchange_pair_id] is wrap the value into an array but not check for similar pair ids. The simplest idea would be using keys in your array. Commented Sep 22, 2017 at 13:15
  • A simple if statement of if pair_id: == 1, etc. and then pushing would suffice in my opinion Commented Sep 22, 2017 at 13:17

5 Answers 5

4

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);

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

1 Comment

Thank you, excellent answer; will research find() further. I actually feel that I could skip this step by performing a better MySQL query, if you do have a moment of your time to see this it may be a way to skip this step. Really appreciated. stackoverflow.com/questions/46365942/…
0

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; }

Comments

0

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 );

Comments

0

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);

1 Comment

This doesnot produce the desired output!
0

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()) 

2 Comments

This solution didn't work I'm afraid: Map { 1=> { pair_id: [1], exchange_pair_id: [183] }, ...
@Nick Happy to help. I tested locally and it seemed to work. What didn't work for you?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.