Nick
Nick

Reputation: 936

Pushing items to an object key's value array

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

Answers (5)

Alejandro C.
Alejandro C.

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

Faly
Faly

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

Suren Srapyan
Suren Srapyan

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

Duncan Thacker
Duncan Thacker

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

Nina Scholz
Nina Scholz

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

Related Questions