从包含特定键的散列数组中删除散列
Remove hash from an array of hash that contains specific keys
我有这个哈希:
{ "car": [
{ "key": 'removeMe1', "name": 'ok' },
{ "key": 'dontRemoveMe1', "surname": 'ok' },
{ "key": 'dontRemoveMe2',
"array": [
{ "trucks": [
{ "key": 'removeMe2', "name": 'my_profile_name' }
] },
{ "trucks": [
{ "key": 'dontRemoveMe3', "name": '34' },
{ "key": 'removeMe3', "surname": '5324' }
]}
] }
]}
我想删除包含 removeMe*
的散列
{ "car": [
{ "key": 'dontRemoveMe1', "surname": 'ok' },
{ "key": 'dontRemoveMe2',
"array": [
{ "trucks": [
{ "key": 'dontRemoveMe3', "name": '34' }
] }
] }
]}
如果我这样做,我在第一级就成功了
my_hash.delete_if { |h| ['removeMe1'].exclude?(h['key']) }
但是我不知道如何为嵌套关卡做。
您可以使用以下解决方案:
def remove_me!(obj)
case obj
when Hash
obj.each_value { |e| remove_me!(e) }
when Array
obj.reject! do |e|
e.is_a?(Hash) && e.values.any? do |v|
v.is_a?(String) && v.start_with?('removeMe')
end
end
obj.each { |e| remove_me!(e) }
end
end
remove_me!(hash)
#=> {:car=>[{:key=>"dontRemoveMe1", :surname=>"ok"},
# {:key=>"dontRemoveMe2", :array=>[{:trucks=>[]}, {:trucks=>[{:key=>"dontRemoveMe3", :name=>"34"}]}]}]}
但请注意,此方法会改变原始对象。您可以使用 dup
创建一个新的。
问题只是关于哈希,但您也可以添加检查空数组并删除它们的部分。
def delete_by_key(data)
data.each do |k, v|
if Array === v
v.each{ |i| delete_by_key(i) }
v.delete_if { |i| i[:key] && i[:key]["removeMe"] or i.empty? }
data.delete(k) if v.empty?
end
end
end
结果如下
data = {
"car": [
{ "key": 'removeMe1', "name": 'ok' },
{ "key": 'dontRemoveMe1', "surname": 'ok' },
{ "key": 'dontRemoveMe2',
"array": [
{ "trucks": [
{ "key": 'removeMe2', "name": 'my_profile_name' }
] },
{ "trucks": [
{ "key": 'dontRemoveMe3', "name": '34' },
{ "key": 'removeMe3', "surname": '5324' }
]}
]
}
]}
delete_by_key(data)
#=> {:car=>[{:key=>"dontRemoveMe1", :surname=>"ok"}, {:key=>"dontRemoveMe2", :array=>[{:trucks=>[{:key=>"dontRemoveMe3", :name=>"34"}]}]}]}
我有这个哈希:
{ "car": [
{ "key": 'removeMe1', "name": 'ok' },
{ "key": 'dontRemoveMe1', "surname": 'ok' },
{ "key": 'dontRemoveMe2',
"array": [
{ "trucks": [
{ "key": 'removeMe2', "name": 'my_profile_name' }
] },
{ "trucks": [
{ "key": 'dontRemoveMe3', "name": '34' },
{ "key": 'removeMe3', "surname": '5324' }
]}
] }
]}
我想删除包含 removeMe*
{ "car": [
{ "key": 'dontRemoveMe1', "surname": 'ok' },
{ "key": 'dontRemoveMe2',
"array": [
{ "trucks": [
{ "key": 'dontRemoveMe3', "name": '34' }
] }
] }
]}
如果我这样做,我在第一级就成功了
my_hash.delete_if { |h| ['removeMe1'].exclude?(h['key']) }
但是我不知道如何为嵌套关卡做。
您可以使用以下解决方案:
def remove_me!(obj)
case obj
when Hash
obj.each_value { |e| remove_me!(e) }
when Array
obj.reject! do |e|
e.is_a?(Hash) && e.values.any? do |v|
v.is_a?(String) && v.start_with?('removeMe')
end
end
obj.each { |e| remove_me!(e) }
end
end
remove_me!(hash)
#=> {:car=>[{:key=>"dontRemoveMe1", :surname=>"ok"},
# {:key=>"dontRemoveMe2", :array=>[{:trucks=>[]}, {:trucks=>[{:key=>"dontRemoveMe3", :name=>"34"}]}]}]}
但请注意,此方法会改变原始对象。您可以使用 dup
创建一个新的。
问题只是关于哈希,但您也可以添加检查空数组并删除它们的部分。
def delete_by_key(data)
data.each do |k, v|
if Array === v
v.each{ |i| delete_by_key(i) }
v.delete_if { |i| i[:key] && i[:key]["removeMe"] or i.empty? }
data.delete(k) if v.empty?
end
end
end
结果如下
data = {
"car": [
{ "key": 'removeMe1', "name": 'ok' },
{ "key": 'dontRemoveMe1', "surname": 'ok' },
{ "key": 'dontRemoveMe2',
"array": [
{ "trucks": [
{ "key": 'removeMe2', "name": 'my_profile_name' }
] },
{ "trucks": [
{ "key": 'dontRemoveMe3', "name": '34' },
{ "key": 'removeMe3', "surname": '5324' }
]}
]
}
]}
delete_by_key(data)
#=> {:car=>[{:key=>"dontRemoveMe1", :surname=>"ok"}, {:key=>"dontRemoveMe2", :array=>[{:trucks=>[{:key=>"dontRemoveMe3", :name=>"34"}]}]}]}