有没有一种优雅的方法可以在多维数组中查找和替换任何大于 3 的整数(例如)?数组的维度可能为 1、2、3 或更大。只是一个这样的数组的例子:
[ [ [ 3, 3, 5 ],
[ 4, 3, 3 ] ],
[ [ 3, 2, 3 ],
[ 0, 3, 8 ] ] ]
我想这样做而不展平数组。
遵循 sepp2k 的想法,这里有一个可能的实现:
class Object
def deep_map(&block)
if self.respond_to? :each
result = []
self.each do |e|
result << e.deep_map(&block)
end
return result
else
return block.call(self)
end
end
end
然后根据需要在阵列上应用deep_map:
> [[[3, 3, 5], [4, 3, 3]], [[3, 2, 3], [0, 3, 8]]].deep_map { |e| e > 3 ? 0 : e }
=> [[[3, 3, 0], [0, 3, 3]], [[3, 2, 3], [0, 3, 0]]]
或者,更简短地说:
class Object
def deep_map(&block)
respond_to?(:map) ? map{|e| e.deep_map(&block)} : block.call(self)
end
end
或者,多态性:
class Object
def deep_map(&block); block.call(self) end
end
class Array
def deep_map(&block); map{|e| e.deep_map(&block)} end
end
您可以编写一个deep_map
方法,该方法在数组上调用map
,然后针对每个元素测试它是否为子数组。如果是,则使用子数组递归调用deep_map
,否则生成元素。
然后,您可以使用该deep_map
方法来转换多维数组的内部元素,而不会影响其结构。
所以,如果我做对了,f(x)
将遍历一个多维数组,直到它找到一个包含不是数组或数组子类的东西,此时它将把最里面的数组交给块,并将其替换为块的返回值。
def f x, &block
x.map do |a|
if a.first.class.ancestors.include? Array
f a, &block
else
yield a
end
end
end
p(f [ [ [ 3, 3, 5 ],
[ 4, 3, 3 ] ],
[ [ 3, 2, 3 ],
[ 0, 3, 8 ] ] ] do |e|
e.reject { |x| x > 3 }
end
)