# Advanced array merging

**URL:** <https://www.ruby-forum.com/t/advanced-array-merging/166809>\
**Category:** Ruby\
**Created:** [April 29, 2009, 7:37pm UTC](https://www.ruby-forum.com/t/advanced-array-merging/166809 "2009-04-29T19:37:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbaty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jbaty](https://www.ruby-forum.com/u/jbaty)\
**Post date:** [April 29, 2009, 7:37pm UTC](https://www.ruby-forum.com/t/advanced-array-merging/166809/1 "2009-04-29T19:37:50Z")

</div>

Hi everyone,

I’m looking for the fastest way (or the version with the least code!) to  
consolidate a couple of arrays.

Basically, what a dump of what I have is this:

[[#\<Ifinoctets\_26 id: 2476, dtime: “2009-04-28 00:00:34”, counter:  
675392602\>, #\<Ifinoctets\_26 id: 2476, dtime: “2009-04-28 00:05:34”,  
counter: 652224867\>, #\<Ifinoctets\_26 id: 2476, dtime: “2009-04-28  
00:10:34”, counter: 637505981\>, #\<Ifinoctets\_26 id: 2476, dtime:  
“2009-04-28 00:15:34”, counter: 813981324\>, #\<Ifinoctets\_26 id: 2476,  
dtime: “2009-04-28 00:20:34”, counter: 753826918\>],

[#\<Ifinoctets\_26 id: 2477, dtime: “2009-04-28 00:00:37”, counter:  
287888720\>, #\<Ifinoctets\_26 id: 2477, dtime: “2009-04-28 00:05:37”,  
counter: 260326966\>, #\<Ifinoctets\_26 id: 2477, dtime: “2009-04-28  
00:10:37”, counter: 287575144\>, #\<Ifinoctets\_26 id: 2477, dtime:  
“2009-04-28 00:15:37”, counter: 341606600\>, #\<Ifinoctets\_26 id: 2477,  
dtime: “2009-04-28 00:20:37”, counter: 305102837\>],

[#\<Ifinoctets\_28 id: 2484, dtime: “2009-04-28 00:00:36”, counter:  
2976043831\>, #\<Ifinoctets\_28 id: 2484, dtime: “2009-04-28 00:05:36”,  
counter: 2904676029\>, #\<Ifinoctets\_28 id: 2484, dtime: “2009-04-28  
00:10:36”, counter: 2901969681\>, #\<Ifinoctets\_28 id: 2484, dtime:  
“2009-04-28 00:15:36”, counter: 2827196523\>, #\<Ifinoctets\_28 id: 2484,  
dtime: “2009-04-28 00:20:36”, counter: 2532538201\>]]

I need to be able to grab the first record of each array (that happens  
to be within the outer array) and merge them into one, keeping the  
class, ID, and dtime of the first of the three and the SUMMED counter of  
all three. In reality there could be anywhere between 2 and 30 arrays in  
there each with any number of records. So let’s say we have:

#\<Ifinoctets\_1 id: 100, dtime: “2009-04-28 00:00:34”, counter: 500\>  
+  
#\<Ifinoctets\_2 id: 111, dtime: “2009-04-28 00:00:37”, counter: 1000\>  
+  
#\<Ifinoctets\_3 id: 122, dtime: “2009-04-28 00:00:36”, counter: 500\>

=

#\<Ifinoctets\_1 id: 100, dtime: “2009-04-28 00:00:34”, counter: 2000\>

---

<div class="post-metadata">

**Author:** ![jbaty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jbaty](https://www.ruby-forum.com/u/jbaty)\
**Post date:** [April 29, 2009, 8:10pm UTC](https://www.ruby-forum.com/t/advanced-array-merging/166809/2 "2009-04-29T20:10:10Z")

</div>

On Wed, Apr 29, 2009 at 11:07 PM, Jack B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> counter: 652224867\>, #\<Ifinoctets\_26 id: 2476, dtime: "2009-04-28
> 
> class, ID, and dtime of the first of the three and the SUMMED counter of
> 
> #\<Ifinoctets\_1 id: 100, dtime: “2009-04-28 00:00:34”, counter: 2000\>

pseudocode:

def add\_octets(x, y)  
ret = x.dup  
ret.counter += y.counter  
ret  
end

ary.inject {|e,i| add\_octets(e,i)}

martin

---

<div class="post-metadata">

**Author:** ![jbaty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jbaty](https://www.ruby-forum.com/u/jbaty)\
**Post date:** [April 30, 2009, 10:37am UTC](https://www.ruby-forum.com/t/advanced-array-merging/166809/3 "2009-04-30T10:37:40Z")

</div>

Jack B. wrote:

> Hi everyone,
> 
> I’m looking for the fastest way (or the version with the least code!) to  
> consolidate a couple of arrays.

Those two requirements are often at odds with each other. For instance,  
“inject” and “fastest” should not be used in the same sentence.

result = []

arr.each do |sub\_arr|  
counter\_total = 0

sub\_arr.each do |obj|  
counter\_total += obj.counter  
end

sub\_arr[0].counter = counter\_total  
result \<\< sub\_arr[0] #or result \<\< [sub\_arr[0]]  
end

---

<div class="post-metadata">

**Author:** ![jbaty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jbaty](https://www.ruby-forum.com/u/jbaty)\
**Post date:** [April 30, 2009, 4:22pm UTC](https://www.ruby-forum.com/t/advanced-array-merging/166809/4 "2009-04-30T16:22:36Z")

</div>

7stud – wrote:

> Those two requirements are often at odds with each other. For instance,  
> “inject” and “fastest” should not be used in the same sentence.
> 
> result = []
> 
> arr.each do |sub\_arr|  
> counter\_total = 0
> 
> sub\_arr.each do |obj|  
> counter\_total += obj.counter  
> end
> 
> sub\_arr[0].counter = counter\_total  
> result \<\< sub\_arr[0] #or result \<\< [sub\_arr[0]]  
> end

Thanks, 7stud. I forgot to mention in my description that after it did  
the sum of the first item in each of the 3 subarrays to move on and do  
all the second items, then the third, etc. Using yours as a base I ended  
up with:

index = 0  
array[0].length.times do  
counter\_total = 0  
array.each do |sub\_array|  
counter\_total += sub\_array[index].counter  
end  
array[0][index].counter = counter\_total  
data\_stream\_out \<\< array[0][index]  
index += 1  
end

Works like a charm and enormously faster than what I was doing before I  
posted this thread. Before I asked for help here I was using inject and  
the calculation was taking 28 seconds to complete. This one took 4 and  
there were about 2,000 more records this time too.

---

<div class="post-metadata">

**Author:** ![jbaty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jbaty](https://www.ruby-forum.com/u/jbaty)\
**Post date:** [April 30, 2009, 11:31pm UTC](https://www.ruby-forum.com/t/advanced-array-merging/166809/5 "2009-04-30T23:31:14Z")

</div>

Jack B. wrote:

> Thanks, 7stud. I forgot to mention in my description that after it did  
> the sum of the first item in each of the 3 subarrays

Whoops. That’s not what my code does–it sums the totals within one  
array. I did a vertical traversal rather than a horizontal traversal.

> move on and do  
> all the second items, then the third, etc. Using yours as a base I ended  
> up with:
> 
> index = 0  
> array[0].length.times do  
> counter\_total = 0  
> array.each do |sub\_array|  
> counter\_total += sub\_array[index].counter  
> end  
> array[0][index].counter = counter\_total  
> data\_stream\_out \<\< array[0][index]  
> index += 1  
> end
> 
> Works like a charm and enormously faster than what I was doing before I  
> posted this thread. Before I asked for help here I was using inject and  
> the calculation was taking 28 seconds to complete. This one took 4 and  
> there were about 2,000 more records this time too.

I read your original post again and with all the talk of merging and  
summing, I decided I have no idea what you are trying to do. If you’ve  
got what you want–great!
