Ruby 修改嵌套哈希的元素

Posted

技术标签:

【中文标题】Ruby 修改嵌套哈希的元素【英文标题】:Ruby modify elements of nested hashes 【发布时间】:2016-12-31 18:46:47 【问题描述】:

我有一个 RoR 应用程序,有时我会收到一些哈希形式的参数。哈希中有一个字段amount 重复。我希望这些字段的值倒置。 这是嵌套哈希的示例:

"name"=>"asdasd", "rate_type"=>"DependantRate",
 "category_rate_requests_attributes"=>
   "0"=>
     "date_from"=>"2016-08-03", "date_to"=>"2016-08-03",
     "room_category_rates_attributes"=>
       "0"=>"r_id"=>"7", "amount"=>"5",
       "1"=>"r_id"=>"98", "amount"=>"15",
       "2"=>"r_id"=>"3", "amount"=>"25",
       "3"=>"r_id"=>"1", "amount"=>"35",
       "4"=>"r_id"=>"115", "amount"=>"45",
       "5"=>"r_id"=>"116", "amount"=>"55",
       "6"=>"r_id"=>"117", "amount"=>"65"
     
   ,
   "1"=>
     "date_from"=>"2016-08-05", "date_to"=>"2016-08-07",
     "room_category_rates_attributes"=>
       "0"=>"r_id"=>"7", "amount"=>"3",
       "1"=>"r_id"=>"98", "amount"=>"13",
       "2"=>"r_id"=>"3", "amount"=>"23",
       "3"=>"r_id"=>"1", "amount"=>"33",
       "4"=>"r_id"=>"115", "amount"=>"43",
       "5"=>"r_id"=>"116", "amount"=>"53",
       "6"=>"r_id"=>"117", "amount"=>"63"
     
   
 

我想获得一个新的哈希值,它的 amountfield 具有相同的值但为负数,如下所示:

"name"=>"asdasd", "rate_type"=>"DependantRate",
 "category_rate_requests_attributes"=>
   "0"=>
     "date_from"=>"2016-08-03", "date_to"=>"2016-08-03",
     "room_category_rates_attributes"=>
       "0"=>"r_id"=>"7", "amount"=>-5,
       "1"=>"r_id"=>"98", "amount"=>-15,
       "2"=>"r_id"=>"3", "amount"=>-25,
       "3"=>"r_id"=>"1", "amount"=>-35,
       "4"=>"r_id"=>"115", "amount"=>-45,
       "5"=>"r_id"=>"116", "amount"=>-55,
       "6"=>"r_id"=>"117", "amount"=>-65
     
   ,
   "1"=>
     "date_from"=>"2016-08-05", "date_to"=>"2016-08-07",
     "room_category_rates_attributes"=>
       "0"=>"r_id"=>"7", "amount"=>-3,
       "1"=>"r_id"=>"98", "amount"=>-13,
       "2"=>"r_id"=>"3", "amount"=>-23,
       "3"=>"r_id"=>"1", "amount"=>-33,
       "4"=>"r_id"=>"115", "amount"=>-43,
       "5"=>"r_id"=>"116", "amount"=>-53,
       "6"=>"r_id"=>"117", "amount"=>-63
     
   
 

(是的,现在的值是数字,但它们是字符串还是数字并不重要,只要它们是负数)。

这是我想出的:

rate_params[:category_rate_requests_attributes].try(:each) do |_key1, category_rate_request|
  category_rate_request[:room_category_rates_attributes].each do |_key2, room_category_rate|
    room_category_rate[:amount] = room_category_rate[:amount].to_i * -1
  end
end

但这远不是好的代码。

有什么建议最好的方法吗?

【问题讨论】:

您的代码看起来很简单。嵌套哈希无能为力。由于您的任务很简单,而我仍然会与您一起使用初始解决方案,这也可以;) new_hash = JSON.parse(old_hash.to_json.gsub(/("amount":")(\d+)(")/ , '\1-\2\3')) 请将示例缩减为基本要素。对于散列,这意味着消除无关的键值对并缩短键和值。此外,为每个输入对象分配一个变量也很有帮助,这样读者就可以在文本和代码中引用这些变量,而无需定义它们。例如,您的整个哈希可能是h = "name"=>"abc", attr1=> 123=> :month=>1, :day=>2 , attr2=> "310"=>"room"=>"7", "amount"=>15, "314"=>"room"=>"98", "amount"=>25 。除此之外,读者现在无需水平滚动即可阅读您的代码。 谢谢你的建议,很快就会去做 【参考方案1】:

除了循环遍历哈希之外,您无能为力。

但是,如果您保证 category_rate_requests 哈希始终是一个元素(关于这是否是一个好主意的争论),您可以使用类似的东西跳过该循环

rate_params["category_rate_requests_attributes"].values.first["room_category_rates_attributes"].each|key, room_category_rate| room_category_rate["amount"] = room_category_rate["amount"].to_i * -1

这假设哈希总是相同的结构,但如果是这种情况,您可以直接获取category_rate_requests_attributes。知道它始终是单元素哈希,使用 values 获取其值的数组,获取该数组的 first(也是唯一的)元素,并循环遍历生成的哈希以反转数量。

我不确定它是否“更好”,但无论如何它是另一条路径。

【讨论】:

以上是关于Ruby 修改嵌套哈希的元素的主要内容,如果未能解决你的问题,请参考以下文章

Ruby Style:如何检查嵌套的哈希元素是不是存在

根据嵌套哈希的内容从哈希中排除元素?

使用键数组遍历嵌套的 Ruby 哈希

ruby 将嵌套数组转换为哈希

Ruby如何格式化嵌套哈希

在Ruby中将嵌套哈希键从CamelCase转换为snake_case