如何深度转换 Ruby 哈希值

lac*_*der 3 ruby hash transform

我有一个看起来像这样的哈希:

hash = {
  'key1' => ['value'],
  'key2' => {
    'sub1' => ['string'],
    'sub2' => ['string'],
  },
  'shippingInfo' => {
                   'shippingType' => ['Calculated'],
                'shipToLocations' => ['Worldwide'],
              'expeditedShipping' => ['false'],
        'oneDayShippingAvailable' => ['false'],
                   'handlingTime' => ['3'],
    }
  }
Run Code Online (Sandbox Code Playgroud)

我需要转换每个值,它是数组中的单个字符串,以便它最终像这样:

hash = {
  'key1' =>  'value' ,
  'key2' => {
    'sub1' => 'string' ,
    'sub2' => 'string' ,
  },
  'shippingInfo' => {
                   'shippingType' => 'Calculated' ,
                'shipToLocations' => 'Worldwide' ,
              'expeditedShipping' => 'false' ,
        'oneDayShippingAvailable' => 'false' ,
                   'handlingTime' => '3' ,
    }
  }
Run Code Online (Sandbox Code Playgroud)

我找到了这个,但无法让它工作 https://gist.github.com/chris/b4138603a8fe17e073c6bc073eb17785

Seb*_*lma 6

怎么样:

def deep_transform_values(hash)
  return hash unless hash.is_a?(Hash)

  hash.transform_values do |val|
    if val.is_a?(Array) && val.length == 1
      val.first
    else
      deep_transform_values(val)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

用类似的东西测试:

hash = {
  'key1' => ['value'],
  'key2' => {
    'sub1' => ['string'],
    'sub2' => ['string'],
  },
  'shippingInfo' => {
                   'shippingType' => ['Calculated'],
                'shipToLocations' => ['Worldwide'],
              'expeditedShipping' => ['false'],
        'oneDayShippingAvailable' => ['false'],
                   'handlingTime' => ['3'],
                   'an_integer' => 1,
                   'an_empty_array' => [],
                   'an_array_with_more_than_one_elements' => [1,2],
                   'a_symbol' => :symbol,
                   'a_string' => 'string'
    }
  }
Run Code Online (Sandbox Code Playgroud)

给出:

{
  "key1"=>"value",
  "key2"=>{
    "sub1"=>"string",
    "sub2"=>"string"
  },
  "shippingInfo"=> {
    "shippingType"=>"Calculated",
    "shipToLocations"=>"Worldwide",
    "expeditedShipping"=>"false",
    "oneDayShippingAvailable"=>"false",
    "handlingTime"=>"3",
    "an_integer"=>1,
    "an_empty_array"=>[],
    "an_array_with_more_than_one_elements"=>[1, 2],
    "a_symbol"=>:symbol,
    "a_string"=>"string"
  }
}
Run Code Online (Sandbox Code Playgroud)

在评论中提出您的问题后,我想逻辑会有所改变:

class Hash
  def deep_transform_values
    self.transform_values do |val|
      next(val.first) if val.is_a?(Array) && val.length == 1
      next(val) unless val.respond_to?(:deep_transform_values)

      val.deep_transform_values
    end
  end
end
Run Code Online (Sandbox Code Playgroud)