下面的代码片段更新了基于哈希类型的值,它几乎按预期工作,但我仍然惊讶地看到Fixnum类型没有完全更新,我的输出低于输出。
输出:
{ :vad_val => "test",
:enabled => nil,
:reg_id => nil,
:buffer_value => 54,
:direct => "test",
:direct_val => "test",
:decision => "test",
:number => 54,
:connections => nil,
:threads => 54,
:updates => nil,
:severity => 54,
:levelval => 54,
:facility => 54,
:depend => "test"
}
从raw_data可以清楚地看到,reg_id和连接是Fixnum所以54是预期的但仍然被nil替换,当类为TrueClass时需要设置nil。这是一个非常小的事情,但作为一个新手,我无法弄清楚。
#!/usr/bin/ruby
require 'json'
raw_data = '{"method_name":"My function","success":true,"payload":[{"Type":"SM::Mod::Elu","Properties":{"TVset":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::VirtualArea","Properties":{"vad_val":{"Type":"String","Mutable":false,"Value":"0001"},"enabled":{"Type":"TrueClass","Mutable":false,"Value":true}},"Children":{"Music":{"Type":"SM::Mod::Base","Properties":{"reg_id":{"Type":"Fixnum","Mutable":true,"Value":null},"buffer_value":{"Type":"Fixnum","Mutable":true,"Value":10},"special_handling_table":{"Type":"SM::Mod::SpecialHandlingTable","Properties":{"behaviors_val":{"Type":"Hash","Mutable":false,"Value":{"1":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::Replace","Properties":{"direct":{"Type":"String","Mutable":true,"Value":"From"}},"Children":{}},{"Type":"SM::Mod::Behavior","Properties":{"direct_val":{"Type":"String","Mutable":true,"Value":"From"}},"Children":{}}],"IsActiveChange":null},"2":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::ReplaceSH","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"Fromnetwork"}},"Children":{}}],"IsActiveChange":null},"3":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::DropBehavior","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"Fromnetwork"}},"Children":{}}],"IsActiveChange":null},"4":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::StripHeaderres","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"ToTransport"}},"Children":{}},{"Type":"SM::Mod::DropBehavior","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"FromTransport"}},"Children":{}}],"IsActiveChange":null},"5":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::StripHeaderBehavior","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"Tosnmp"}},"Children":{}},{"Type":"SM::Mod::DropBehavior","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"FromTransport"}},"Children":{}}],"IsActiveChange":null},"6":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::ReplaceSHBehavior","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"Fromconn"}},"Children":{}}],"IsActiveChange":null},"7":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::Dropfem","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"FromTransport"}},"Children":{}}],"IsActiveChange":null},"8":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::Dropfem","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"From"}},"Children":{}}],"IsActiveChange":null},"9":{"Type":"Array","Mutable":false,"Value":[{"Type":"SM::Mod::DropBehavior","Properties":{"decision":{"Type":"String","Mutable":true,"Value":"From"}},"Children":{}}],"IsActiveChange":null}},"IsActiveChange":null}},"Children":{}}},"Children":{}}}}],"IsActiveChange":null},"number":{"Type":"Fixnum","Mutable":false,"Value":0,"IsActiveChange":false},"connections":{"Type":"Fixnum","Mutable":true,"Value":null},"threads":{"Type":"Fixnum","Mutable":true,"Value":4},"updates":{"Type":"TrueClass","Mutable":true,"Value":null},"severity":{"Type":"Fixnum","Mutable":true,"Value":3},"levelval":{"Type":"Fixnum","Mutable":true,"Value":3},"facility":{"Type":"Fixnum","Mutable":true,"Value":3},"trace":{"Type":"smode::Depval::Fallback","Properties":{"enabled":{"Type":"TrueClass","Mutable":true,"Value":false},"depend":{"Type":"String","Mutable":false,"Value":""}},"Children":{}}},"Children":{}}],"error":""}'
def create_hash(set, result = {})
if set.class == Hash # iterate through hash
#result.compare_by_identity
set.each do |k, v|
if v.class == Hash && %w(String TrueClass Fixnum).include?((v["Type"] || ''))
result[k.to_sym] = v["Value"] # add this key's value to the output array
if v["Value"].class==String
result[k.to_sym]="test"
elsif v["Value"].class==Fixnum
result[k.to_sym]=54
else v["Value"].class==TrueClass
result[k.to_sym]=nil
end
elsif v.class == Hash || v.class == Array
result = create_hash(v, result) # check nested arrays and hashes
end
end
elsif set.class == Array
set.each do |a|
result = create_hash(a, result) # check elements of an array
end
end
result
end
val = create_hash(JSON.parse(raw_data))
p val
答案 0 :(得分:1)
{"reg_id":{"Type":"Fixnum","Mutable":true,"Value":null}
所以在If语句中
v["Value"].class == Fixnum
错误,因为nil.class == NilClass
。所以在你的情况下你应该检查它不是这样的:
v["Value"].class == Fixnum
但是
v["Type"] == "Fixnum"
答案 1 :(得分:1)
if v["Value"].class==String
result[k.to_sym]="test"
elsif v["Value"].class==Fixnum
result[k.to_sym]=54
else v["Value"].class==TrueClass
result[k.to_sym]=nil
end
在代码的上方部分,您正在检查"值"如果v.class是哈希。对于连接哈希,连接["值"]为空,而不是Fixnum。
"connections": {
"Type": "Fixnum",
"Mutable": true,
"Value": null
}
这就是原因,你对它不予理会。 p>
答案 2 :(得分:1)
我不知道你想要实现什么,但你的做法是错误的。让我粘贴工作代码:
json = JSON.parse raw_data
def parse_hash hash
hash.inject([]) { |memo, kv|
next memo unless kv.last.is_a?(Enumerable)
if kv.last.is_a? Array
kv.last.each { |kv|
memo += parse_hash kv
}
else
if kv.last.has_key?('Type') &&
kv.last.has_key?('Value') &&
!kv.last['Value'].is_a?(Enumerable)
memo << [kv.first, [kv.last['Type'], kv.last['Value']]]
end
memo += parse_hash kv.last
end
memo
}
end
听起来我们抓住了我们想要的任何东西。但是等等:
ap parse_hash(json).map { |el|
value = case el.last.first
when 'Fixnum' then Integer(el.last.last || 0)
when 'TrueClass' then !!el.last.last
else el.last.last
end
[el.first.to_sym, value]
}.inject({}) { |memo, el|
if memo.has_key?(el.first)
memo[el.first] = [memo[el.first]] unless memo[el.first].is_a? Array
memo[el.first] << el.last
else
memo[el.first] = el.last
end
memo
}
给我们:
{
:buffer_value => 10,
:connections => 0,
:decision => [
[0] "Fromnetwork",
[1] "Fromnetwork",
[2] "ToTransport",
[3] "FromTransport",
[4] "Tosnmp",
[5] "FromTransport",
[6] "Fromconn",
[7] "FromTransport",
[8] "From",
[9] "From"
],
:depend => "",
:direct => "From",
:direct_val => "From",
:enabled => [
[0] true,
[1] false
],
:facility => 3,
:levelval => 3,
:number => 0,
:reg_id => 0,
:severity => 3,
:threads => 4,
:updates => false,
:vad_val => "0001"
}
也就是说,输入数据包含两个enabled
键和≈10decision
s。代码自愿采取最后一个,这是无稽之谈。所以,你试图得到的最终结果毫无意义,因为它会使价值变得混乱。
尽管如此,我想我提供了一些关于进一步发展的提示。