I started using Enumerable#detect. Decided to have a little fun with procs.
#!/Users/orionengleton/.rvm/rubies/ruby-2.1.1/bin/ruby | |
log = [ | |
{time: 201201, x: 2},{time: 201201, y: 7},{time: 201201, z: 2}, | |
{time: 201202, a: 3},{time: 201202, b: 4},{time: 201202, c: 0} | |
] | |
# Required - Results. | |
required_result = [{:time=>201201, :x=>2, :y=>7, :z=>2}, {:time=>201202, :a=>3, :b=>4, :c=>0}] | |
# Using global variables * and #Procs | |
new_log = [] | |
mergeit = ->(g, h) { g.merge!(h) } | |
insert_new = ->(h) { new_log << h } | |
smash = ->(_array) { | |
for i in _array do | |
new_log << i if new_log.empty? | |
new_log.map { |g| | |
r = new_log.detect {|h| h[:time] == i[:time] } | |
r ? mergeit.call(r, i) : insert_new.call(i) | |
} | |
end | |
new_log | |
} | |
# Using #inject method | |
_result = log.inject([]) { |array, h| | |
# Using a ternary would seem tempting but.. | |
# checker = array.detect {|i| i[:time] == h[:time] } ? checker.merge!(h) : array << h | |
# because ruby also evaluates from left > right this does not work - checcker is not set in time. | |
if checker = array.detect {|i| i[:time] == h[:time] } | |
checker.merge!(h) | |
else | |
array << h | |
end | |
array | |
}.inject(log) { |log, h| | |
_result ||= [] | |
_result << h; _result | |
} | |
# Fourth Attempt * All procs.b | |
allprocs = log.inject([]) {|array, h| | |
# Ternary * | |
-> { @checker = array.detect {|i| i[:time] == h[:time] } }.call() ? @checker.merge!(h) : array << h | |
array | |
}.inject(log) {|log, v| | |
allprocs ||= [] | |
allprocs << v | |
allprocs | |
} | |
# Also usinject reverse conditional logic - unless not if. | |
result = log.inject([]) {|b, c| | |
unless hsh = b.detect {|i| i[:time] == c[:time] } | |
b << c | |
else | |
hsh.merge!(c) | |
end | |
b | |
}.inject(log) {|ac, d| | |
result ||= [] | |
result << d; result | |
} | |
puts ( result | smash.call(log) | _result | allprocs ) == required_result |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment