来自ruby hash的嵌套json

问题描述 投票:0回答:5

尝试从Ruby哈希中构建json

require 'json'
temp_rides = {"rides": {}}
rides = {:lyft => "car", :scoot => "scooter", :blade => "helicopter"}
rides.each do |key, value|
 temp_rides["rides"].push({"key" => "value"})
 puts temp_rides
end

显然,它无法通过undefined method push'`失败,我相信我需要在追加之前加载json对象(基于我的python背景)。

我正在寻找类似这样的输出

{
    "rides": {
        "lyft": {
            "type": "car"
        },
        "scoot": {
            "type": "scooter"
        },
        "blade": {
            "type": "helicopter"
        }
    }
}
ruby
5个回答
1
投票

这是对OP原始问题的回答。我对更改它以尝试回答移动目标没有兴趣。

代码

def doit(rides)
  { rides: rides.slice_before { |k,_| k.to_s.match? /\Aride\d*\z/ }.
                 map { |a| hashify(a.flatten.drop(1)) }.
                 reduce(&:merge) }
end

def hashify(arr)
  f,*rest = arr
  return f if rest.empty?
  { f.to_sym=>hashify(rest) }
end

示例

这里是(递归)辅助方法hashify的使用示例:

hashify ["lyft", :type, "car"]
  #=> {:lyft=>{:type=>"car"}} 

我们得到了哈希rides

rides = {:ride1=>"lyft", :type=>"car", :ride2=>"Scoot",
         :type2=>"scooter", :ride3=>"blade", :type3=>"helicopter"} 
doit rides
  #=> {:rides=>{:lyft=>{:type=>"car"},
  #             :Scoot=>{:type2=>"scooter"},
  #             :blade=>{:type3=>"helicopter"}}} 

让我们将更多键/值对添加到rides

rides = {:ride1=>"lyft", :type=>"car", :color=>"blue",
         :ride2=>"Scoot", :type2=>"scooter", :make=>"Vespa", :model=>"98",
         :ride3=>"blade", :type3=>"helicopter"} 
doit rides
  #=> {:rides=>{:lyft=>{:type=>{:car=>{:color=>"blue"}}},
  #             :Scoot=>{:type2=>{:scooter=>{:make=>
  #                       {:Vespa=>{:model=>"98"}}}}},
  #             :blade=>{:type3=>"helicopter"}}} 

说明

第一个示例的步骤如下。

enum = rides.slice_before { |k,_| k.to_s.match? /\Aride\d*\z/ }
  #=> #<Enumerator: #<Enumerator::Generator:0x00005a49d68217f0>:each> 

我们可以看到此枚举器将其转换为数组所生成的元素。

enum.to_a
  #=> [[[:ride1, "lyft"], [:type, "car"]],
  #    [[:ride2, "Scoot"], [:type2, "scooter"]],
  #    [[:ride3, "blade"], [:type3, "helicopter"]]] 

继续,

a = enum.map { |a| hashify(a.flatten.drop(1)) }
  #=> [{:lyft=>{:type=>"car"}},
  #    {:Scoot=>{:type2=>"scooter"}},
  #    {:blade=>{:type3=>"helicopter"}}] 
h = a.reduce(&:merge)
  #=> {:lyft=>{:type=>"car"}, :Scoot=>{:type2=>"scooter"},
  #    :blade=>{:type3=>"helicopter"}} 
{ rides: h } 
  #=> <as above> 

0
投票

实际上,通过简单的转换就很容易做到:

def rejig(rides)
  rides.map do |name, type|
    [ name, { type: type } ]
  end.to_h
end

将您的结构重新加工成所需形状的位置。

使用起来很容易:

require 'json'

rides = { lyft: "car", scoot: "scooter", blade: "helicopter" }

puts JSON.dump(rejig(rides))
# => {"lyft":{"type":"car"},"scoot":{"type":"scooter"},"blade":{"type":"helicopter"}}

0
投票

它给了您undefined method push,因为没有用于散列的此类方法。

temp_rides = {"rides": {}} 
# This create a hash with `:rides` symbol as the key {:rides=>{}}

# To push an object into a hash. Use operator[]= or #store method
temp_rides[:rides][:key1] = 'value1'
temp_rides[:rides].store(:key2, 'value2')

一个工作示例:

require 'json'

temp_rides = {"rides": {}}
rides = {:lyft => "car", :scoot => "scooter", :blade => "helicopter"}
rides.each_pair do |k, v|
    temp_rides[:rides][k] = {:type => v}
end

puts JSON.pretty_generate(temp_rides)

0
投票
require 'json'
temp_rides = {"rides": {}}
rides = {:lyft => "car", :scoot => "scooter", :blade => "helicopter"}
temp_rides[:rides].merge!(rides)

获取ruby哈希输出

temp_rides

获取json格式输出

JSON.dump temp_rides

0
投票
require 'json'

rides = {:lyft => "car", :scoot => "scooter", :blade => "helicopter"}

transformed = {
  'rides' => rides.inject({}) { |h,(k,v)| h[k] = { 'type' => v }; h }
}

JSON.dump(transformed)
© www.soinside.com 2019 - 2024. All rights reserved.