[英]Delete nested hash according to key => value
我有这个哈希:
response = '{"librairies":[{"id":1,"books":[{"id":1,"qty":1},{"id":2,"qty":3}]},{"id":2,"books":[{"id":1,"qty":0},{"id":2,"qty":3}]}]}'
在这里,我想删除所有书目数量至少为空的书目。
例如,通过给定的response
,我希望得到以下返回:
'{"librairies":[{"id":1,"books":[{"id":1,"qty":1},{"id":2,"qty":3}]}]}'
我已经试过了:
parsed = JSON.parse(response)
parsed["librairies"].each do |library|
library["books"].each do |book|
parsed.delete(library) if book["qty"] == 0
end
end
但这会返回完全相同的response
哈希,而不会删除第二个库(id => 2的那个库)。
您可以使用Array#delete_if和Enumerable#any吗? 为了这
# Move through each array element with delete_if
parsed["librairies"].delete_if do |library|
# evaluates to true if any book hash in the library
# has a "qty" value of 0
library["books"].any? { |book| book["qty"] == 0 }
end
希望这可以帮助
为了避免更改已parsed
的哈希,您可以执行以下操作。
首先,让我们parsed
格式,以便我们可以看到正在处理的内容:
parsed = { "libraries"=>[ { "id"=>1,
"books"=>[ { "id"=>1, "qty"=>1 },
{ "id"=>2, "qty"=>3 } ]
},
{ "id"=>2,
"books"=>[ { "id"=>1, "qty"=>0 },
{ "id"=>2, "qty"=>3 } ]
}
]
}
稍后,我想说明在创建新哈希时parsed
内容没有更改。 一种简单的方法是在前后parsed
上计算哈希码,并查看其是否更改。 (虽然不能100%地确定不同的哈希值不会具有相同的哈希码,但是这里没有什么值得浪费的时间。)
parsed.hash
#=> 852445412783960729
我们首先需要对parsed
文件进行“深度复制”,以使对该副本所做的更改不会影响parsed
。 一种方法是使用Marshal模块:
new_parsed = Marshal.load(Marshal.dump(parsed))
现在,我们可以根据需要修改副本:
new_parsed["libraries"].reject! { |h| h["books"].any? { |g| g["qty"].zero? } }
#=> [ { "id"=>1,
# "books"=>[ { "id"=>1, "qty"=>1 },
# { "id"=>2, "qty"=>3 }
# ]
# }
# ]
new_parsed # => { "libraries"=>[ { "id"=>1,
"books"=>[ { "id"=>1, "qty"=>1},
{ "id"=>2, "qty"=>3}
]
}
]
}
并且我们确认原始哈希没有更改:
parsed.hash
#=> 852445412783960729
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.