示例:
array = [ [ [ [ ["foo"] ] ] ] ]
array[0][0][0][0][0] == "foo" # => true
在这种情况下,我知道数组的深度是5,所以我可以使用
array[0][0][0][0][0]
访问其中的内容。
我的问题是:如果我有depth = ?
,每次程序运行时?
都不同,我如何在Ruby中访问(写入)嵌套数组中的元素。 (我假设每个数组只有一个子数组)。
答案 0 :(得分:3)
你需要一个递归函数:
def innermost(x)
(x.is_a? Array) ? innermost(x[0]) : x
end
array = [ [ [ [ ["foo"] ] ] ] ]
innermost(array)
# => "foo"
<强>更新强>
更新后的版本返回最里面的数组而不是数组的元素。
def innermost(x)
(x[0].is_a? Array) ? innermost(x[0]) : x
end
array = [ [ [ [ ["foo"] ] ] ] ]
a = innermost(array) # => ["foo"]
a[0] = 'bar'
array
# => [[[[["bar"]]]]]
答案 1 :(得分:2)
如果数组只包含一个数据,则可以使用flatten。
array = [ [ [ [ ["foo"] ] ] ] ]
array.flatten[0]
=> "foo"
答案 2 :(得分:0)
[编辑:我试图太可爱了,它咬了我一下。最初我提出了两种使用array.to_s[/\[+/].size
确定级别数的方法。使用eval
将字符串转换为输出数组的方法之一。 @FrederickCheung指出了两个瑕疵(谢谢,弗雷德里克),你可以在评论中看到。如果您想查看我的原始答案,您当然可以查看编辑内容。我现在编辑了建议我最初提出的第一种方法的更传统的变体。的潮强>
这是一种非递归方法。
def replace_foo(array, val)
a = array
nbr_levels = (1..Float::INFINITY).find { |i| !(a=a.first).is_a? Array }
nbr_levels.times.reduce(val) { |a,_| [a] }
end
array = [ [ [ [ ["foo"] ] ] ] ]
#=> [[[[["foo"]]]]]
replace_foo(array, { our_dog: "Diva", our_cat: "Teagan" })
#=> [[[[[{:our_dog=>"Diva", :our_cat=>"Teagan"}]]]]]