我有一个哈希里面有很多哈希,值可能是一个数组,这个数组由许多哈希组成,我想打印所有键值对,如果值是数组,那么它必须打印
"pageOfResults": "Array" # I don't want actual array here, I want the string "Array" to be printed.
如果哈希如下,则需要打印
"PolicyPayment": "Hash"
其他需要打印键和值
Key -> "CurrencyCode":
Value-> "SGD",
哈希跟随
a={
"PageOfResults": [
{
"CurrencyCode": "SGD",
"IpAddress": nil,
"InsuranceApplicationId": 6314,
"PolicyNumber": "SL10032268",
"PolicyPayment": {
"PolicyPaymentId": 2188,
"PaymentMethod": "GIRO"
},
"InsuranceProductDiscountDetail": nil,
"ProductDetails": {
"Results": [
{
"Id": 8113,
"InsuranceProductId": 382,
"ApplicationProductSelectedId": 62043,
},
"InsuranceProduct": {
"InsuranceProductId": 382,
"ProductCode": "TL70-90",
},
],
},
}
]
}
我编写的程序用于打印这些值
a.each do |key,value|
puts "key->" + key.to_s
if value.is_a?Array
value.each do |v|
v.each do |key,value|
puts "key->"+key.to_s
puts "value->"+value.to_s
end
end
else
puts "value->"+value.to_s
end
这个程序首先打印哈希值和它的值,我可以做递归调用来打印所有值,
但我的问题是,有没有什么方法可以编写Ruby风格的代码来轻松实现这一目标?还是更好的方式?
答案 0 :(得分:4)
简单的 λ
可以解决问题:
printer = ->(enum) do
enum.each do |k, v|
enum = [k, v].detect(&Enumerable.method(:===))
if enum.nil?
puts("Key -> #{k}\nValue -> #{v}")
else
puts ("#{k} -> 'Array'") if v.is_a?(Array)
printer.(enum)
end
end
end
printer.(a)
产:
PageOfResults -> 'Array'
Key -> CurrencyCode
Value -> SGD
Key -> IpAddress
Value ->
Key -> InsuranceApplicationId
Value -> 6314
Key -> PolicyNumber
Value -> SL10032268
Key -> PolicyPaymentId
Value -> 2188
Key -> PaymentMethod
Value -> GIRO
Key -> InsuranceProductDiscountDetail
Value ->
Results -> 'Array'
Key -> Id
Value -> 8113
Key -> InsuranceProductId
Value -> 382
Key -> ApplicationProductSelectedId
Value -> 62043
Key -> InsuranceProductId
Value -> 382
Key -> ProductCode
Value -> TL70-90
答案 1 :(得分:1)
我使用了递归,希望这对你有所帮助。
def traverse_multid_array(arr)
arr.each do |ele|
if ele.class == Array
traverse_multid_array(ele)
elsif ele.class == Hash
traverse_nested_hash(ele)
end
end
end
def traverse_nested_hash(hash)
hash.each do |key,value|
if value.class == Array
puts "#{key} => Array"
traverse_multid_array(value)
elsif value.class == Hash
puts "#{key} => Hash"
traverse_nested_hash(value)
else
puts "Key => #{key}"
puts "Value => #{value}"
end
end
end
traverse_nested_hash(a)
输出结果:
PageOfResults => Array
Key => CurrencyCode
Value => SGD
Key => IpAddress
Value =>
Key => InsuranceApplicationId
Value => 6314
Key => PolicyNumber
Value => SL10032268
PolicyPayment => Hash
Key => PolicyPaymentId
Value => 2188
Key => PaymentMethod
Value => GIRO
Key => InsuranceProductDiscountDetail
Value =>
ProductDetails => Hash
Results => Array
Key => Id
Value => 8113
Key => InsuranceProductId
Value => 382
Key => ApplicationProductSelectedId
Value => 62043
InsuranceProduct => Hash
Key => InsuranceProductId
Value => 382
Key => ProductCode
Value => TL70-90
答案 2 :(得分:1)
您可以按照here所述优化Hash::each
,即添加以下代码:
module HashRecursive
refine Hash do
def each(recursive=false, &block)
if recursive
Enumerator.new do |yielder|
self.map do |key, value|
value.each(recursive=true).map do |key_next, value_next|
yielder << [[key, key_next].flatten, value_next]
end if value.is_a?(Hash)
yielder << [[key], value]
end
end.entries.each(&block)
else
super(&block)
end
end
alias_method(:each_pair, :each)
end
end
using HashRecursive
之后,此代码将完全您要求的内容:
def whatsInside(hashOrArray)
hashOrArray.each(recursive=true) do |key, value|
type = value.class.to_s
case type
when "Array", "Hash"
puts key.pop.to_s.inspect+": "+type.inspect
value.each do |valueInArray|
whatsInside(valueInArray)
end if value.is_a?(Array)
else
puts "Key -> "+key.pop.to_s.inspect+":"
puts "Value-> "+value.inspect+","
end
end
end
whatsInside(a)
输出如下:
Key -> "CurrencyCode":
Value-> "SGD",
Key -> "IpAddress":
Value-> nil,
Key -> "InsuranceApplicationId":
Value-> 6314,
Key -> "PolicyNumber":
Value-> "SL10032268",
Key -> "PolicyPaymentId":
Value-> 2188,
Key -> "PaymentMethod":
Value-> "GIRO",
"PolicyPayment": "Hash"
Key -> "InsuranceProductDiscountDetail":
Value-> nil,
"Results": "Array"
Key -> "Id":
Value-> 8113,
Key -> "InsuranceProductId":
Value-> 382,
Key -> "ApplicationProductSelectedId":
Value-> 62043,
Key -> "InsuranceProductId":
Value-> 382,
Key -> "ProductCode":
Value-> "TL70-90",
"InsuranceProduct": "Hash"
"ProductDetails": "Hash"
然而,我认为这就是你想要的:
def whatsInside(hashOrArray)
hashOrArray.each(recursive=true) do |key, value|
if value.is_a?(Array)
puts "Entering array #{key}"
value.each { |valueInArray| whatsInside(valueInArray) }
else
puts "#{key} => #{value}" unless value.is_a?(Hash)
end
end
end
whatsInside(a)
将返回此:
Entering array [:PageOfResults]
[:CurrencyCode] => SGD
[:IpAddress] =>
[:InsuranceApplicationId] => 6314
[:PolicyNumber] => SL10032268
[:PolicyPayment, :PolicyPaymentId] => 2188
[:PolicyPayment, :PaymentMethod] => GIRO
[:InsuranceProductDiscountDetail] =>
Entering array [:ProductDetails, :Results]
[:Id] => 8113
[:InsuranceProductId] => 382
[:ApplicationProductSelectedId] => 62043
[:InsuranceProduct, :InsuranceProductId] => 382
[:InsuranceProduct, :ProductCode] => TL70-90
答案 3 :(得分:1)
@pos = 0
@inc = 2
def indent() @pos += @inc end
def undent() @pos -= @inc end
def prs(str); print ' '*@pos; puts str; end
def pr(k,v); prs "key->#{k}"; prs "value->#{v}"; end
def print_values(h)
h.each do |k,v|
case v
when Array
pr(k, "Array")
indent
v.each do |h|
prs "Hash"
indent
print_values(h)
undent
end
undent
when Hash
pr(k, "Hash")
indent
print_values(v)
undent
else
pr(k,v)
end
end
end
print_values a
key->PageOfResults
value->Array
Hash
key->CurrencyCode
value->SGD
key->IpAddress
value->
key->InsuranceApplicationId
value->6314
key->PolicyNumber
value->SL10032268
key->PolicyPayment
value->Hash
key->PolicyPaymentId
value->2188
key->PaymentMethod
value->GIRO
key->InsuranceProductDiscountDetail
value->
key->ProductDetails
value->Hash
key->Results
value->Array
Hash
key->Id
value->8113
key->InsuranceProductId
value->382
key->ApplicationProductSelectedId
value->62043
Hash
key->InsuranceProduct
value->Hash
key->InsuranceProductId
value->382
key->ProductCode
value->TL70-90