gpt4 book ai didi

json - 在 Ruby 中通过路径替换和访问嵌套 hash/json 中的值

转载 作者:行者123 更新时间:2023-12-03 09:00:23 24 4
gpt4 key购买 nike

寻求建议,您认为使用 ruby​​ 通过路径 ir 变量替换和访问嵌套哈希或 json 中的值的最佳和简单的解决方案是什么?

例如,假设我有具有这种结构的 json 或 hash:

{  
"name":"John",
"address":{
"street":"street 1",
"country":"country1"
},
"phone_numbers":[
{
"type":"mobile",
"number":"234234"
},
{
"type":"fixed",
"number":"2342323423"
}
]
}

我想通过可以在变量中指定的路径访问或更改固定手机号码,如下所示:“phone_numbers/1/number”(在这种情况下分隔符并不重要)

此解决方案对于从 json/hash 检索值以及有时通过指定变量的路径来替换变量是必要的。找到了一些可以通过键查找值的解决方案,但该解决方案不起作用,因为存在一些哈希/json,其中键名称在多个位置相同。

我看到了这个:https://github.com/chengguangnan/vine ,但是当有效负载像这样时它不起作用,因为在这种情况下它不是一种哈希:

[  
{
"value":"test1"
},
{
"value":"test2"
}
]

希望您有一些解决这个问题的好主意。

谢谢!

编辑:所以我用这些数据尝试了下面的代码:

    x = JSON.parse('[  
{
"value":"test1"
},
{
"value":"test2"
}
]')



y = JSON.parse('{
"name":"John",
"address":{
"street":"street 1",
"country":"country1"
},
"phone_numbers":[
{
"type":"mobile",
"number":"234234"
},
{
"type":"fixed",
"number":"2342323423"
}
]
}')

p x
p y.to_h
p x.get_at_path("0/value")
p y.get_at_path("name")

得到这个:

[{"value"=>"test1"}, {"value"=>"test2"}]
{"name"=>"John", "address"=>{"street"=>"street 1", "country"=>"country1"}, "phone_numbers"=>[{"type"=>"mobile", "number"=>"234234"}, {"type"=>"fixed", "number"=>"2342323423"}]}
hash_new.rb:91:in `<main>': undefined method `get_at_path' for [{"value"=>"test1"}, {"value"=>"test2"}]:Array (NoMethodError)

对于 y.get_at_path("name") 得到 nil

最佳答案

您可以使用Hash.dig为了获取子值,它将继续对每个步骤的结果调用 dig 直到到达末尾,并且 Array has dig as well ,所以当你到达该数组时,事情将继续工作:

# you said the separator wasn't important, so it can be changed up here
SEPERATOR = '/'.freeze

class Hash
def get_at_path(path)
dig(*steps_from(path))
end

def replace_at_path(path, new_value)
*steps, leaf = steps_from path

# steps is empty in the "name" example, in that case, we are operating on
# the root (self) hash, not a subhash
hash = steps.empty? ? self : dig(*steps)
# note that `hash` here doesn't _have_ to be a Hash, but it needs to
# respond to `[]=`
hash[leaf] = new_value
end

private
# the example hash uses symbols as the keys, so we'll convert each step in
# the path to symbols. If a step doesn't contain a non-digit character,
# we'll convert it to an integer to be treated as the index into an array
def steps_from path
path.split(SEPERATOR).map do |step|
if step.match?(/\D/)
step.to_sym
else
step.to_i
end
end
end
end

然后就可以这样使用(hash 包含您的示例输入):

p hash.get_at_path("phone_numbers/1/number") # => "2342323423"
p hash.get_at_path("phone_numbers/0/type") # => "mobile"
p hash.get_at_path("name") # => "John"
p hash.get_at_path("address/street") # => "street 1"

hash.replace_at_path("phone_numbers/1/number", "123-123-1234")
hash.replace_at_path("phone_numbers/0/type", "cell phone")
hash.replace_at_path("name", "John Doe")
hash.replace_at_path("address/street", "123 Street 1")

p hash.get_at_path("phone_numbers/1/number") # => "123-123-1234"
p hash.get_at_path("phone_numbers/0/type") # => "cell phone"
p hash.get_at_path("name") # => "John Doe"
p hash.get_at_path("address/street") # => "123 Street 1"

p hash
# => {:name=>"John Doe",
# :address=>{:street=>"123 Street 1", :country=>"country1"},
# :phone_numbers=>[{:type=>"cell phone", :number=>"234234"},
# {:type=>"fixed", :number=>"123-123-1234"}]}

关于json - 在 Ruby 中通过路径替换和访问嵌套 hash/json 中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51012203/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com