# To\_hash

**URL:** <https://www.ruby-forum.com/t/to-hash/180731>\
**Category:** Rails\
**Created:** [December 28, 2009, 6:57am UTC](https://www.ruby-forum.com/t/to-hash/180731 "2009-12-28T06:57:08Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![jasonwold](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e36b37/32.png) [@jasonwold](https://www.ruby-forum.com/u/jasonwold)\
**Post date:** [December 28, 2009, 6:57am UTC](https://www.ruby-forum.com/t/to-hash/180731/1 "2009-12-28T06:57:08Z")

</div>

# 

# Author : Jason Wang

# Date : 2009/28/12

# mailto: removed\_email\_address@domain.invalid

# 

# 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
