Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails merging two arrays of hashes?

I'm having a hard time grasping the logic I'd need to merge two arrays of hashes, It seems I've asked this question a while back in sort of a different way, I've also tried a few other things like the answers offered here: merging arrays of hashes

Any sort of help understanding this would be really helpful to me.

Say I have the following array, and this is output from the method itself, so you can imagine those :timestamps to be Time objects

[
  {:timestamp=>2011-12-19 00:00:00 UTC},
  {:timestamp=>2011-12-19 01:00:00 UTC},
  {:timestamp=>2011-12-19 02:00:00 UTC},
  {:timestamp=>2011-12-19 03:00:00 UTC},
  {:timestamp=>2011-12-19 04:00:00 UTC},
  {:timestamp=>2011-12-19 05:00:00 UTC}
]

And then an additional array like this, each of which has another value (but sometimes may have a bunch more values besides :count)

[
  {:timestamp=>2011-12-19 02:00:00 UTC, :count=>5},
  {:timestamp=>2011-12-19 04:00:00 UTC, :count=>21}
]

And result in something like this:

[
  {:timestamp=>2011-12-19 00:00:00 UTC},
  {:timestamp=>2011-12-19 01:00:00 UTC},
  {:timestamp=>2011-12-19 02:00:00 UTC, :count=>5},
  {:timestamp=>2011-12-19 03:00:00 UTC},
  {:timestamp=>2011-12-19 04:00:00 UTC, :count=>21},
  {:timestamp=>2011-12-19 05:00:00 UTC}
]

Again, thanks for your help, I'm not sure why I just can't figure out the proper design pattern for this.

like image 880
JP Silvashy Avatar asked Dec 20 '11 00:12

JP Silvashy


2 Answers

it looks like you first group by timestamp and then merge the values:

(a1+a2).group_by{|h| h[:timestamp]}.map{|k,v| v.reduce(:merge)}
like image 177
pguardiario Avatar answered Oct 04 '22 04:10

pguardiario


a = [
  {:timestamp=>'2011-12-19 00:00:00 UTC'},
  {:timestamp=>'2011-12-19 01:00:00 UTC'},
  {:timestamp=>'2011-12-19 02:00:00 UTC'},
  {:timestamp=>'2011-12-19 03:00:00 UTC'},
  {:timestamp=>'2011-12-19 04:00:00 UTC'},
  {:timestamp=>'2011-12-19 05:00:00 UTC'}
]

b = [
  {:timestamp=>'2011-12-19 02:00:00 UTC', :count=>5},
  {:timestamp=>'2011-12-19 04:00:00 UTC', :count=>21}
]

result = a.inject([]) do |memo, v|
  if match = b.detect { |w| (w.to_a & v.to_a).any? }
    memo << match.merge(v)
  else
    memo << v
  end
end

p result
like image 38
d11wtq Avatar answered Oct 04 '22 02:10

d11wtq