Skip to content

Instantly share code, notes, and snippets.

@rsgrafx

rsgrafx/gist:9862471

Created Mar 29, 2014
Embed
What would you like to do?
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