I’m continuing my look at Ruby Facets today, this time looking at another Hash
method. I use Hashes everyday in Rails programming so if I can pick up some new techniques, I can put them to use right away. Today’s subject is Hash#zipnew
.
The Code
1 2 3 4 5 6 |
# File lib/core/facets/hash/zipnew.rb, line 11 def self.zipnew(keys,values) # or some better name h = {} keys.size.times{ |i| h[ keys[i] ] = values[i] } h end |
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#!/usr/bin/ruby -wKU # # Code Reading #2 require '../base' require "facets/hash/zipnew" class HashZipnew def data keys = [ '2010-05-15', '2010-05-16', '2010-05-17', '2010-05-18', '2010-05-19' ] values = [ 100.0, 450.5, 89.0, 0.0, 78.5 ] Hash.zipnew(keys, values) end end ap(HashZipnew.new.data) class HashZipnewTest < Test::Unit::TestCase def test_use_the_arrays_to_map_keys_to_values hashish = HashZipnew.new.data assert_equal 100.0, hashish['2010-05-15'] assert_equal 450.5, hashish['2010-05-16'] assert_equal 89.0, hashish['2010-05-17'] assert_equal 0.0, hashish['2010-05-18'] assert_equal 78.5, hashish['2010-05-19'] end end |
Review
Hash#zipnew
is a awesome method. I can’t remember how many times I’ve collected two sets of time based data and had to merge them together, like when graphing time data. Hash#zipnew
is pretty simple to use, just feed it two arrays of data; one for the keys and one for the values.
Internally, Hash#zipnew
takes the size of the keys
array and adds a new key/value to a hash. Running the loop by hand in irb shows this for the first two elements:
1 2 3 4 5 6 7 |
>> h = {} {} >> h['2010-05-15'] = 100.0 100.0 >> h['2010-05-16'] = 450.5 450.5 >> ... |
I really like how #zipnew
makes use of Array#size
and Fixnum#times
to automatically control it’s loops.
Since code reading should be an active activity, I’ve also created an alternative implementation that uses Array#with_index
which would remove the #size
and #times
method calls.
1 2 3 4 5 |
def self.alt_zipnew(keys, values) h = {} keys.each_with_index {|key, index| h[ key ] = values[ index ] } h end |
This is the reason I’m interested in rubinius. Since they are using Ruby for (almost) the entire virtual machine, anyone can dig into the Ruby source code and play around with the internal implementation.