在Ruby多维数组中查找和替换

时间:2011-05-20 22:20:26

标签: ruby arrays multidimensional-array

在多维数组中是否有一种优雅的方法来查找和替换优于3(例如)的任何整数?阵列可以具有尺寸1,2,3或更多。只是一个这样的数组的例子:

[ [ [ 3, 3, 5 ], 
    [ 4, 3, 3 ] ], 
  [ [ 3, 2, 3 ], 
    [ 0, 3, 8 ] ] ]

我想在没有压扁阵列的情况下这样做。

3 个答案:

答案 0 :(得分:5)

遵循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

答案 1 :(得分:2)

您可以编写一个deep_map方法,在数组上调用map,然后为每个元素测试它是否是一个子数组。如果是,则用子数组递归调用deep_map,否则产生元素。

然后,您可以使用deep_map方法转换多维数组的内部元素,而不会影响其结构。

答案 2 :(得分:0)

所以,如果我做得对,f(x)将遍历一个多维数组,直到它找到一个包含 Array Array <的子类的数据。 / em>,此时它将产生最内层的 Array 到块中,并用块的返回值替换它。

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
)