简体   繁体   English

将ruby结构转换为哈希

[英]Converting a ruby structure to a hash

I've got a bit of a headache here - I'm pretty new to Ruby... 我在这里有点头疼-我是Ruby的新手...

I've got a structure like so returned from Savon... 我有一个类似的结构,从Savon返回...

{
  :item => [{
              :key =>  "result",
              :value=> "success"
            },
            {
              :key =>  "data",
              :value=> {
                  :item => [{ :key => "displayName", 
                              :value => "Matt" 
                            },
                            {
                              :key => "messages",
                              :value => { 
                                  :items => [{....}]
                            }
                       ]
               }
       }]
}

And I need to get it to be like... 我需要让它像...

{
  :result => success
  :data => [{
              :displayName => "Matt"
           },
           {
              :messages => [{
                              :messageName => "Test Message"
                           }]
           }]
}

So I can easily manipulate and navigate the data structure I've tried a few methods including just passing the value of :item ... 因此,我可以轻松地操纵和导航我尝试了几种方法的数据结构,包括仅传递:item的值...

def convertData(data)
  result = {}
  if(data!=nil)
    data.each do |item|
      key = item[:key] 
      value = item[:value] 
      if(value.instance_of?(Hash))
        result[key] = convertData(value[:item])
      else
        result[key] = value
      end  
    end
  end
  return result
end

But this just gives me a tonne of Type errors for symbol to integer conversion (I assume that's the array index playing up). 但这只是给了我大量从符号到整数转换的Type错误(我假设这是正在播放的数组索引)。 Any help much appreciated. 任何帮助,不胜感激。

When trying to tackle problem like this in Ruby, it's useful to think of it in terms of transformations on your data. 当尝试在Ruby中解决此类问题时,从数据转换的角度考虑它很有用。 The Ruby Enumerable library is full of methods that help you manipulate regular data structures like Array and Hash. Ruby Enumerable库充满了各种方法,可以帮助您操纵常规数据结构,例如Array和Hash。

A Ruby solution to this problem looks like: Ruby解决此问题的方法如下:

def desavon(data)
  case (data)
  when Hash
    if (data[:item])
      data[:item].collect do |item|
        { item[:key] => desavon(item[:value]) }
      end
    else
      # raise error?
    end
  else
    data
  end
end

Here's some sample input data and sample output: 以下是一些示例输入数据和示例输出:

input = {
  item: [
    {
      key: "result",
      value: "success"
    },
    {
      key:  "data",
      value: {
        item: [
          {
            key: "displayName", 
            value: "Matt" 
          },
          {
            key: "messages",
            value: { 
              item: [
                {
                  key: 'messageName',
                  value: 'Test Message'
                }
              ]
            }
          }
        ]
      }
    }
  ]
}

desavon(input)
# => [{"result"=>"success"}, {"data"=>[{"displayName"=>"Matt"}, {"messages"=>[{"messageName"=>"Test Message"}]}]}]

I think this version looks better, output-wise, but that's a call you'll have to make: 我认为此版本在输出方面看起来更好,但这是您必须做出的选择:

def desavon(data)
  case (data)
  when Hash
    if (data[:item])
      Hash[
        data[:item].collect do |item|
          [ item[:key], desavon(item[:value]) ]
        end
      ]
    else
      # raise error?
    end
  else
    data
  end
end

desavon(input)
# => {"result"=>"success", "data"=>{"displayName"=>"Matt", "messages"=>{"messageName"=>"Test Message"}}}

Note that the case statement here is really the key, it allows you to quickly differentiate between different types of data you're converting, and the Hash[] method converts key-value pairs into the Hash structure you're looking for. 请注意,这里的case语句确实是关键,它允许您快速区分要转换的不同类型的数据,并且Hash[]方法将键值对转换为您要寻找的Hash结构。

This is similar to your attempt, but just passes through content it doesn't recognize as-is. 这与您的尝试类似,但是只是通过无法原样识别的内容。

Savon provides a to_hash method on the result. Savon对结果提供一个to_hash方法。 What I usually do is: 我通常要做的是:

... ...

response = @client.request :wsdl, :conversion_rate do
  soap.body = {
    "FromCurrency" => from_curr,
    "ToCurrency" => to_curr
  }
end    
response.to_hash[:conversion_rate_response][:conversion_rate_result];

... full script here https://gist.github.com/sroller/3d04842ab763f52b6623 ...完整的脚本在这里https://gist.github.com/sroller/3d04842ab763f52b6623

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM