类图像使用0和1的数组进行初始化。我有方法transform
,这样
[[0,0,0],
[0,1,0],
[0,0,0]]
返回
[[0,1,0],
[1,1,1],
[0,1,0]]
我想实现方法blur(n),它使用transform迭代n次,例如使用
调用blur(2)[[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0]]
返回
[[0,0,0,0,1,0,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,1,1,1,1,1,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,0,1,0,0,0,0]]
我正在尝试迭代地使用变换来实现这一点,但是在使用Image实例调用blur时我得到了undefined method 'map' for #<Context::Image:0x000000012eb020>
。如何迭代每个连续的转换,以便模糊返回最新版本的最大n次转换?
class Image
attr_accessor :array
def initialize(array)
self.array = array
end
def output_image
self.array.each do |item|
puts item.join
end
end
def transform #changes adjacent a 1's adjacent 0's into 1
cloned = self.array.map(&:clone)
#scan original array for 1; map crosses into clone if found
self.array.each.with_index do |row, row_index|
row.each.with_index do |cell, col|
if cell == 1
cloned[row_index][col+1] = 1 unless col+1 >= row.length #copy right
cloned[row_index+1][col] = 1 unless row_index+1 >= cloned.length # copy down
cloned[row_index][col-1] = 1 unless col.zero? # copy left
cloned[row_index-1][col] = 1 unless row_index.zero? #copy up
end
end
end
cloned
end
def blur(n) #should call transform iteratively n times
blurred = Image.new(self)
n.times do
blurred = blurred.transform
end
blurred
end
end
答案 0 :(得分:1)
map
是Array
可用的方法,但不适用于您的自定义类Image
。
我建议您在实例变量map
上调用@array
。然后,在完成转换后,使用该转换后的数组创建一个新的Image
实例。
以下是应该有效的代码示例。请注意,transform和blur将输入数组作为参数,因此它们不依赖于任何实例状态。因此,我已经使它们成为类方法而不是实例方法。这允许用户在不必创建实例的情况下使用它们,如果他们想要做的就是数组转换。它还使这些方法在将来的重构中很容易提取到模块中。我添加了一个实例方法blurred_image
,它将转换应用于实例并返回一个新的Image
实例。
def self.transform(input_array) #changes adjacent a 1's adjacent 0's into 1
cloned = input_array.map(&:clone)
#scan original array for 1; map crosses into clone if found
input_array.each.with_index do |row, row_index|
row.each.with_index do |cell, col|
if cell == 1
cloned[row_index][col+1] = 1 unless col+1 >= row.length #copy right
cloned[row_index+1][col] = 1 unless row_index+1 >= cloned.length # copy down
cloned[row_index][col-1] = 1 unless col.zero? # copy left
cloned[row_index-1][col] = 1 unless row_index.zero? #copy up
end
end
end
cloned
end
def self.blur(input_array, transform_count) #should call transform iteratively n times
blurred = input_array
transform_count.times { blurred = transform(blurred) }
Image.new(blurred)
end
def blurred_image(transform_count)
self.class.new(self.class.blur(array, transform_count))
end
答案 1 :(得分:1)
您可以使用Matrix类。
require 'matrix'
class Matrix
def el(r,c)
if r < 0 || r >= row_count || c < 0 || c >= column_count
0
else
self[r,c]
end
end
def transform
Matrix.build(row_count, column_count) { |r,c|
[el(r,c), el(r-1,c), el(r+1,c), el(r,c-1), el(r,c+1)].max }
end
end
给定行 - 列对r, c
,如果行或列超出矩阵的边界,则辅助方法el
返回0,否则返回值[r,c]
。 / p>
nrows = 5
ncols = 5
m = Matrix.build(nrows, ncols) { |r,c| (r==nrows/2 && c==ncols/2) ? 1 : 0 }
#=> Matrix[[0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 0, 1, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0]]
m = m.transform
#=> Matrix[[0, 0, 0, 0, 0],
# [0, 0, 1, 0, 0],
# [0, 1, 1, 1, 0],
# [0, 0, 1, 0, 0],
# [0, 0, 0, 0, 0]]
m = m.transform
# Matrix[[0, 0, 1, 0, 0],
# [0, 1, 1, 1, 0],
# [1, 1, 1, 1, 1],
# [0, 1, 1, 1, 0],
# [0, 0, 1, 0, 0]]
m.to_a
#=> [[0, 0, 1, 0, 0],
# [0, 1, 1, 1, 0],
# [1, 1, 1, 1, 1],
# [0, 1, 1, 1, 0],
# [0, 0, 1, 0, 0]]