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

发布于 2024-11-08 23:02:54 字数 202 浏览 0 评论 0原文

有没有一种优雅的方法来查找和替换多维数组中大于 3 的任何整数(例如)?该数组的维度可以是 1、2、3 或更多。只是此类数组的一个示例:

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

我想在不展平数组的情况下这样做。

Is there an elegant way to find and replace any integers superior to 3 (as example) in a multidimensional array? The array may have the dimension 1, 2, 3, or more. Just an example of a such array:

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

I would like to do so without flatten the array.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

最偏执的依靠 2024-11-15 23:02:54

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

Following sepp2k idea, here is a possible implementation:

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

Then apply deep_map as you wish on the array:

> [[[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]]] 

Or, more briefly:

class Object
  def deep_map(&block)
    respond_to?(:map) ? map{|e| e.deep_map(&block)} : block.call(self)
  end
end

Or, polymorphically:

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
千纸鹤带着心事 2024-11-15 23:02:54

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

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

You can write a deep_map method, which calls map on the array and then for each element test whether it's a sub-array. If it is, call deep_map recursively with the sub-array, otherwise yield the element.

You can then use that deep_map method to transform the inner elements of your multi-dimensional array without affecting its structure.

不交电费瞎发啥光 2024-11-15 23:02:54

因此,如果我做得正确,f(x) 将遍历多维数组,直到找到一个包含非 数组子类的内容的数组。 >Array,此时它将生成块最里面的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
)

So, if I've done this right, f(x) will traverse a multidimensional Array until it finds one containing something that isn't an Array or subclass of Array, at which point it will yield the innermost Array to the block and replace it with the block's return value.

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
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文