Ruby on rails 从嵌套哈希中删除所有相似的键
给定如下哈希:Ruby on rails 从嵌套哈希中删除所有相似的键,ruby-on-rails,ruby,Ruby On Rails,Ruby,给定如下哈希: { id: 1, name: "test", children: [ { id: 1, name: "kid 1" }, { id: 2, name: "kid 2" } ] } 如何递归删除所有id键?您可以编写一个递归遍历哈希和数组的函数 def delete_recursively(thing, key_to_delete) case thing when Hash # Delete the key thing.de
{
id: 1,
name: "test",
children: [
{ id: 1, name: "kid 1" },
{ id: 2, name: "kid 2" }
]
}
如何递归删除所有
id
键?您可以编写一个递归遍历哈希和数组的函数
def delete_recursively(thing, key_to_delete)
case thing
when Hash
# Delete the key
thing.delete(key_to_delete)
# Recurse into each remaining hash value.
thing.each_value do |value|
delete_recursively(value, key_to_delete)
end
when Array
# Recurse into each value of the array.
thing.each do |value|
delete_recursively(value, key_to_delete)
end
end
end
这可以根据需要扩展为包括其他数据类型。这当然需要递归解决方案。下面的方法不会改变原始散列 代码
def recurse(obj, key_to_delete)
case obj
when Array
obj.map { |e| recurse(e, key_to_delete) }
else # hash
obj.reject { |k,_| k == key_to_delete }.transform_values do |v|
case v
when Hash, Array
recurse(v, key_to_delete)
else
v
end
end
end
end
h = { id: 1, name: "test", children: [
{ id: 1, name: "kid 1" }, { id: 2, name: "kid 2", grandkids: [
{ id: 3, name: "gkid1" }] }
]
}
示例
def recurse(obj, key_to_delete)
case obj
when Array
obj.map { |e| recurse(e, key_to_delete) }
else # hash
obj.reject { |k,_| k == key_to_delete }.transform_values do |v|
case v
when Hash, Array
recurse(v, key_to_delete)
else
v
end
end
end
end
h = { id: 1, name: "test", children: [
{ id: 1, name: "kid 1" }, { id: 2, name: "kid 2", grandkids: [
{ id: 3, name: "gkid1" }] }
]
}
解释
递归方法执行的操作总是很难解释。根据我的经验,最好的方法是在代码中添加puts语句。然而,这本身是不够的,因为在查看输出时,很难跟踪递归的级别,在该级别上,特定的结果是获得的,或者传递给自身,或者返回给自身的版本。解决方法是缩进和取消缩进结果,这就是我在下面所做的。请注意,我构造代码的方式和我使用的几个助手方法是相当通用的,因此这种方法可以适用于检查其他递归方法执行的操作
INDENT = 8
@col = -INDENT
def indent; @col += INDENT; end
def undent; @col -= INDENT; end
def pu(s); print " "*@col; puts s; end
def puhline; pu('-'*(70-@col)); end
15分钟后开始。不错。
recurse(h, :id)
----------------------------------------------------------------------
passed obj = {:id=>1, :name=>"test", :children=>[{:id=>1, :name=>"kid 1"},
{:id=>2, :name=>"kid 2", :grandkids=>[{:id=>3, :name=>"gkid1"}]}]},
key_to_delete = id
obj with :id removed={:name=>"test", :children=>[{:id=>1, :name=>"kid 1"},
{:id=>2, :name=>"kid 2", :grandkids=>[{:id=>3, :name=>"gkid1"}]}]}
in tranform_values, v=test
keeping the literal v
in tranform_values, v=[{:id=>1, :name=>"kid 1"},
{:id=>2, :name=>"kid 2", :grandkids=>[{:id=>3, :name=>"gkid1"}]}]
v is Hash or Arrary
calling recurse([{:id=>1, :name=>"kid 1"},
{:id=>2, :name=>"kid 2", :grandkids=>[{:id=>3, :name=>"gkid1"}]}], id)...
--------------------------------------------------------------
passed obj = [{:id=>1, :name=>"kid 1"},
{:id=>2, :name=>"kid 2", :grandkids=>[{:id=>3, :name=>"gkid1"}]}],
key_to_delete = id
processing Array...
calling recurse({:id=>1, :name=>"kid 1"}, id)...
------------------------------------------------------
passed obj = {:id=>1, :name=>"kid 1"}, key_to_delete = id
obj with :id removed={:name=>"kid 1"}
in tranform_values, v=kid 1
keeping the literal v
returning {:name=>"kid 1"}
------------------------------------------------------
calling recurse({:id=>2, :name=>"kid 2",
:grandkids=>[{:id=>3, :name=>"gkid1"}]}, id)...
------------------------------------------------------
passed obj = {:id=>2, :name=>"kid 2", :grandkids=>
[{:id=>3, :name=>"gkid1"}]},
key_to_delete = id
obj with :id removed={:name=>"kid 2", :grandkids=>
[{:id=>3, :name=>"gkid1"}]}
in tranform_values, v=kid 2
keeping the literal v
in tranform_values, v=[{:id=>3, :name=>"gkid1"}]
v is Hash or Arrary
calling recurse([{:id=>3, :name=>"gkid1"}], id)...
----------------------------------------------
passed obj = [{:id=>3, :name=>"gkid1"}],
key_to_delete = id
processing Array...
calling recurse({:id=>3, :name=>"gkid1"}, id)...
--------------------------------------
passed obj = {:id=>3, :name=>"gkid1"},
key_to_delete = id
obj with :id removed={:name=>"gkid1"}
in tranform_values, v=gkid1
keeping the literal v
returning {:name=>"gkid1"}
--------------------------------------
returning [{:name=>"gkid1"}]
----------------------------------------------
returning {:name=>"kid 2", :grandkids=>[{:name=>"gkid1"}]}
------------------------------------------------------
returning [{:name=>"kid 1"},
{:name=>"kid 2", :grandkids=>[{:name=>"gkid1"}]}]
--------------------------------------------------------------
returning {:name=>"test", :children=>[{:name=>"kid 1"},
{:name=>"kid 2", :grandkids=>[{:name=>"gkid1"}]}]}
----------------------------------------------------------------------
#=> {:name=>"test", :children=>[{:name=>"kid 1"},
{:name=>"kid 2", :grandkids=>[{:name=>"gkid1"}]}]}