#
# Author : Jason Wang
# Date : 2009/28/12
# mailto: hxpwork-KN7UnAbNpbg@public.gmane.org
#
# 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
--
Posted via http://www.ruby-forum.com/.
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.