将嵌套哈希中的值注入到字符串中

时间:2017-02-03 17:55:37

标签: json ruby

我正在尝试将变量注入JSON字符串。我认为有一种简单的方法可以做到这一点,但我还没有找到它。这是基本目标。我有一个JSON字符串,我想将变量注入其中。我有一个多维哈希,我想从中提取数组。

JSON:

{"room":"814","token":"myfaketoken","message":"The test passed with status %{result.status} from test %{test}"

哈希:

hash = {:result => {:success => true, :status => 'healthy'}, :test => example}
newString = json % hash

这适用于非嵌套的东西,但我没有找到嵌套东西的简单替代方法。

3 个答案:

答案 0 :(得分:0)

如果您正在使用json,第一步是将json转换为散列,然后将其作为散列处理,并在完成后将其转换回json。您可以使用json module轻松完成此操作。

示例:

首先要求文件顶部的json模块:

require 'json'

...

hash_from_json = {"room":"814","token":"myfaketoken","message":"The test passed with status %{result.status} from test %{test}"}
=> {:room=>"814", :token=>"myfaketoken", :message=>"The test passed with status %{result.status} from test %{test}"}

现在用哈希做你想做的事。即类似的东西:

hash_from_json[:message] = "The test passed with status %{result.status} from test %{test}"

然后将其转换回json

formatted_json = hash_from_json.to_json
 => "{\"room\":\"814\",\"token\":\"myfaketoken\",\"message\":\"The test passed with status %{result.status} from test %{test}\"}"

答案 1 :(得分:0)

我认为字符串格式%不能用于嵌套哈希。

但是,您可以使用gsub和块来手动解析字符串。该块将%{result.status}转换为[:result, :status],并将此数组与Hash#dig一起使用(需要Ruby 2.3+):

message = 'The test passed with status %{result.status} from test %{test}'
hash = { result: { success: true, status: 'healthy' }, test: 'example' }

new_message = message.gsub(/%\{(.*?)\}/) do
  hash.dig(*Regexp.last_match(1).split('.').map(&:to_sym)) 
end

p new_message
#=> "The test passed with status healthy from test example"

答案 2 :(得分:0)

一个选项是展平嵌套哈希:

def flatten hash, del='_', prefix=''
  new = {}
  hash.each do |k, v|
    if v.respond_to? :keys 
      new.merge! flatten(v, del, "#{prefix}#{k}#{del}")
    else
      new["#{prefix}#{k}".to_sym] = v
    end
  end
  return new
end

使用它看起来像这样:

> h = {one: "blah", two: {three: "foo", bar: "gah"}}
 => {:one=>"blah", :two=>{:three=>"foo", :bar=>"gah"}} 
> flatten h
 => {:one=>"blah", :two_three=>"foo", :two_bar=>"gah"} 
> flatten h, '.'
 => {:one=>"blah", :"two.three"=>"foo", :"two.bar"=>"gah"}

这将比gsub / regex答案更昂贵,但它应该适用于旧版本的ruby。