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"
我想获得一个新的哈希值,它的 amount
field 具有相同的值但为负数,如下所示:
"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 修改嵌套哈希的元素的主要内容,如果未能解决你的问题,请参考以下文章