G
Greg Hauptmann
[Note: parts of this message were removed to make it a legal post.]
Hi,
I wanted a way to be able to "add" values to a Hash such that it keeps the
old and the new values. For examples example adding an item to a hash for
which the keys are dates. Here's a first cut. Any feedback on coding
style etc?
================================
class Hash
# Merges a hash with only one item into your hash. If there is already a
# hash entry for that key the both existing value(s) & new value are kept
via
# use of an Array
def merge_add!(h)
raise "Parameter passed in not a hash" if !h.instance_of?(Hash)
raise "Can only pass hash with one item to be added" if h.length > 1
h_key = h.to_a[0][0]
h_value = h.to_a[0][1]
if self.has_key?(h_key)
existing_value = self[h_key]
existing_value_as_array = existing_value.instance_of?(Array) ?
existing_value : [existing_value]
new_value = existing_value_as_array << h_value
self[h_key] = new_value
else
h_value.instance_of?(Array) ? self.merge!(h) : self.merge!( {h_key =>
[h_value]} )
end
end
end
================================
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe "merge_add!" do
beforeeach) do
@empty_hash = {}
@hash_with_number = {100 => 1}
@hash_with_array = {100 => [1]}
end
it "should raise an error if there is no object passed to the method" do
lambda{ @empty_hash.merge_add!() }.should raise_error(ArgumentError)
end
it "should raise an error if the object passed is not a Hash" do
lambda{@empty_hash.merge_add!(123)}.should raise_error(RuntimeError,
"Parameter passed in not a hash")
end
it "should raise an error if the number of items in the hash in not 1" do
lambda{@empty_hash.merge_add!({101 => 2, 102 => 3})}.should
raise_error(RuntimeError, "Can only pass hash with one item to be added")
end
it "should create a new Array & wrap new value as an array" do
@empty_hash.merge_add!( {101 => 2} )
@empty_hash[101].should eql([2])
end
it "should create a new Array & use the array passed as the value" do
@empty_hash.merge_add!( {101 => [2]} )
@empty_hash[101].should eql([2])
end
it "should migrate existing value to an Array, then add the new value, if
existing value is NOT an array" do
@hash_with_number.merge_add!( {100 => 2} )
@hash_with_number[100].should eql([1, 2])
end
it "should migrate add the new value to existing, if existing value IS an
array" do
@hash_with_array.merge_add!( {100 => 2} )
@hash_with_array[100].should eql([1, 2])
end
end
================================
tks
Hi,
I wanted a way to be able to "add" values to a Hash such that it keeps the
old and the new values. For examples example adding an item to a hash for
which the keys are dates. Here's a first cut. Any feedback on coding
style etc?
================================
class Hash
# Merges a hash with only one item into your hash. If there is already a
# hash entry for that key the both existing value(s) & new value are kept
via
# use of an Array
def merge_add!(h)
raise "Parameter passed in not a hash" if !h.instance_of?(Hash)
raise "Can only pass hash with one item to be added" if h.length > 1
h_key = h.to_a[0][0]
h_value = h.to_a[0][1]
if self.has_key?(h_key)
existing_value = self[h_key]
existing_value_as_array = existing_value.instance_of?(Array) ?
existing_value : [existing_value]
new_value = existing_value_as_array << h_value
self[h_key] = new_value
else
h_value.instance_of?(Array) ? self.merge!(h) : self.merge!( {h_key =>
[h_value]} )
end
end
end
================================
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe "merge_add!" do
beforeeach) do
@empty_hash = {}
@hash_with_number = {100 => 1}
@hash_with_array = {100 => [1]}
end
it "should raise an error if there is no object passed to the method" do
lambda{ @empty_hash.merge_add!() }.should raise_error(ArgumentError)
end
it "should raise an error if the object passed is not a Hash" do
lambda{@empty_hash.merge_add!(123)}.should raise_error(RuntimeError,
"Parameter passed in not a hash")
end
it "should raise an error if the number of items in the hash in not 1" do
lambda{@empty_hash.merge_add!({101 => 2, 102 => 3})}.should
raise_error(RuntimeError, "Can only pass hash with one item to be added")
end
it "should create a new Array & wrap new value as an array" do
@empty_hash.merge_add!( {101 => 2} )
@empty_hash[101].should eql([2])
end
it "should create a new Array & use the array passed as the value" do
@empty_hash.merge_add!( {101 => [2]} )
@empty_hash[101].should eql([2])
end
it "should migrate existing value to an Array, then add the new value, if
existing value is NOT an array" do
@hash_with_number.merge_add!( {100 => 2} )
@hash_with_number[100].should eql([1, 2])
end
it "should migrate add the new value to existing, if existing value IS an
array" do
@hash_with_array.merge_add!( {100 => 2} )
@hash_with_array[100].should eql([1, 2])
end
end
================================
tks