To_hash

Author : Jason Wang

Date : 2009/28/12

mailto: [email protected]

The code convert an array to hash by specified method of the object in

the array.

Examples

class Address

attr_accessor :street, :city

def initialize(street, city)

@street = street

@city = city

end

end

class Info

attr_accessor :name, :code, :place, :age

def initialize(name, code, place=nil)

@name = name

@code = code

@place = place

@age = 25

end

end

def get_info_array

return Array.new([

Info.new(“Jason”,“111”, Address.new(“long”,“gz”)),

Info.new(“Pony”,“222”, Address.new(“chang”,“gz”)),

Info.new(“Jason”,“333”, Address.new(“short”,“gx”))])

end

arr = get_info_array

then, you can use like that…

1) arr.to_hash({ :key => “name” })

hash --> { “Jason” => arr[2] , “Pony” => arr[1] }

**note: if key repeat, later value covered before value

2) arr.to_hash({ :key => “name”, :value =>“code” })

hash --> { “Jason” => “333” , “Pony” => “222” }

3) arr.to_hash({ :key1 => “name” , :key2 => “code” , :value =>

“place.city” })

hash --> { “Jason-111” => “gz” , “Pony-222” => “gz” , “Jason-333”

=> “gx” }

4) arr.to_hash_array( { :key => “name” } )

hash --> { “Jason” => [ arr[0], arr[2] ] , “Pony” => [ arr[1] ]

**note: if key repeat, later value append to array

5) arr.to_hash_array({ :key => “name”, :value =>“code” })

hash --> { “Jason” => [ “111” , “333” ] , “Pony” => [ “222” ] }

6) arr.to_hash_array({ :key1 => “name” , :key2 => “code” , :value =>

“place.city” })

hash --> { “Jason-111” => [“gz”] , “Pony-222” => [“gz”] ,

“Jason-333” => [“gx”] }

module Enumerable
def to_hash( params )
dict_block(self,params){ |dict,obj,params|
hash_get_key_value(obj,params) { |key,value| dict[key] = value } }
end

def to_hash_array(params)
dict_block(self,params){ |dict,obj,params|
hash_get_key_value(obj,params) { |key,value| dict_array(dict,value,key)
} }
end

private

def hash_get_key_value(obj, params)
return if params.nil?
key = get_method_key(obj,params[:key]) if params.include?(:key)
key = get_two_key(obj,params[:key1],params[:key2]) if
params.include?(:key1) && params.include?(:key2)
return if key.nil?
obj = get_method_key(obj,params[:value]) unless params[:value].nil?
yield key , obj
end

def dict_block(list, params)
dict = Hash.new
return dict if list.nil?
if ( list.methods.include?(“each”))
list.each do |obj|
yield dict, obj, params
end
else
yield dict, list, params
end
dict
end

def dict_array(dict,obj,key)
return if key.nil?
dict.has_key?(key) ? dict[key] << obj : dict[key] = Array.new([obj])
end

def get_two_key(obj,key1,key2)
key1_value = get_method_key(obj,key1)
key2_value = get_method_key(obj,key2)
return nil if key1_value.nil? || key2_value.nil?
“#{key1_value}-#{key2_value}”
end

def get_method_key( obj, methodName )
return nil if methodName.nil?
methodName.split(".").each do |m_name|
return nil unless obj.methods.include?(m_name)
obj = obj.method(m_name).call
end
obj
end
end