给定一个嵌套数组或散列作为接收器,并将某个对象作为参数,如果接收器包含该对象,则返回路径到对象出现的最佳方法是什么nil?我将路径定义为数组索引或散列键的数组,导致该对象.参数对象永远不会是任何哈希键,并且永远不会出现多次.例如,我希望:
[
:a,
[:b, :c, {:d => :foo}],
:e,
]
.path_to(:foo) # => [1, 2, :d]
{
:a => [3, "foo"],
:b => 5,
:c => 2,
}
.path_to(3) # => [:a, 0]
Run Code Online (Sandbox Code Playgroud)
如果没有发生,请返回nil:
[:foo, "hello", 3]
.path_to(:bar) => nil
Run Code Online (Sandbox Code Playgroud)
如果没有人提出合理的答案,那么我很快就会发布自己的答案.
没有什么比一点递归更好的了。
require 'minitest/autorun'
class Array
def path_to(obj)
# optimize this
Hash[self.each.with_index.to_a.map {|k,v| [v,k]}].path_to(obj)
end
end
class Hash
def path_to(obj)
inverted = self.invert
if inverted[obj]
[inverted[obj]]
else
self.map {|k, v|
if v.respond_to?(:path_to)
if res = v.path_to(obj)
[k] + res
end
end
}.find {|path|
path and path[-1] != nil
}
end
end
end
describe "path_to" do
it "should work with really simple arrays" do
[:a, :e,].path_to(:a).must_equal [0]
end
it "should work with simple arrays" do
[:a, [:b, :c], :e,].path_to(:c).must_equal [1, 1]
end
it "should work with arrays" do
[:a, [:b, :c, {:d => :foo}], :e,].path_to(:foo).must_equal [1, 2, :d]
end
it "should work with simple hashes" do
{:d => :foo}.path_to(:foo).must_equal [:d]
end
it "should work with hashes" do
({:a => [3, "foo"], :b => 5, :c => 2,}.path_to(3).must_equal [:a, 0])
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |