Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何将数组中的nil转换为0以获得和?_Arrays_Ruby_Sum_Conways Game Of Life - Fatal编程技术网

Arrays 如何将数组中的nil转换为0以获得和?

Arrays 如何将数组中的nil转换为0以获得和?,arrays,ruby,sum,conways-game-of-life,Arrays,Ruby,Sum,Conways Game Of Life,在康威的《生活游戏》中,我使用2d数组进行工作,当我试图计算每个细胞的“邻居”之和时,我总是被nil值挡住 def neighbor_count grid.each_with_index do |row, idx| row.each_with_index do |column, idx2| [grid[idx - 1][idx2 - 1], grid[idx - 1][idx2], grid[idx - 1][idx2 + 1],

在康威的《生活游戏》中,我使用2d数组进行工作,当我试图计算每个细胞的“邻居”之和时,我总是被nil值挡住

  def neighbor_count
      grid.each_with_index do |row, idx|
          row.each_with_index do |column, idx2|
              [grid[idx - 1][idx2 - 1], grid[idx - 1][idx2], grid[idx - 1][idx2 + 1],
              grid[idx][idx2 - 1], grid[idx][idx2], grid[idx][idx2 + 1],
              grid[idx + 1][idx2 - 1], grid[idx + 1][idx2], grid[idx + 1][idx2 + 1]
              ].compact.sum

          end
      end
  end
.compact似乎在数组前面包含“puts”时效果最好,但我尝试过的选项中没有一个是100%。我尝试过reduce(:+)、inject、.to_I、reject(去掉nil值)等等

这里少了什么

错误:world.rb:35:in
块(2级)中的邻居计数:nil:NilClass(NoMethodError)的未定义方法


第35行是上面的那行。)compact.sum

nil值只是疾病的症状。不要治疗症状,解决问题!也就是说您违反了数组边界

。每个带有索引的索引都会枚举从第一个到最后一个的所有索引。因此,最后一个索引上的
idx+1
将触发这种越界情况。和
idx-1
在第一个上会产生一个意外的值,而不是一个错误,这将影响您的计算。祝你好运。:)

在你的代码中加入一些守卫检查,以确保你永远不会越界



需要明确的是,问题不在于
grid[idx+1][idx2]
为零并且会打乱您的计算。这是因为
网格[idx+1]
为零!而且,很自然,您不能执行
nil[idx2]
。这就是错误所在。

零值只是疾病的症状。不要治疗症状,解决问题!也就是说您违反了数组边界

。每个带有索引的索引都会枚举从第一个到最后一个的所有索引。因此,最后一个索引上的
idx+1
将触发这种越界情况。和
idx-1
在第一个上会产生一个意外的值,而不是一个错误,这将影响您的计算。祝你好运。:)

在你的代码中加入一些守卫检查,以确保你永远不会越界



需要明确的是,问题不在于
grid[idx+1][idx2]
为零并且会打乱您的计算。这是因为
网格[idx+1]
为零!而且,很自然,您不能执行
nil[idx2]
。这就是错误。

声明您的网格有一层边界,那么就不需要添加额外的if/else子句,也可以使用方向向量访问循环中的邻居

#let say you want to delare 4x4 grid, declare grid of (row+2, col+2)
row, col, default_value = 4, 4, 0
grid = Array.new(row+2){Array.new(col+2,default_value)}

# store direction vectors dx and dy
dx = [-1, -1, -1, 0, 1, 1, 1, 0, 0]
dy = [-1, 0, 1, 1, 1, 0, -1, -1, 0]
(1..row).each do |i|
  (1..col).each do |j|
      puts (0..8).reduce(0) { |sum, k| sum + grid[i + dx[k]][j + dy[k]]}
end

用一层边界声明你的网格,这样就不需要额外的if/else子句,也可以使用方向向量访问循环中的邻居

#let say you want to delare 4x4 grid, declare grid of (row+2, col+2)
row, col, default_value = 4, 4, 0
grid = Array.new(row+2){Array.new(col+2,default_value)}

# store direction vectors dx and dy
dx = [-1, -1, -1, 0, 1, 1, 1, 0, 0]
dy = [-1, 0, 1, 1, 1, 0, -1, -1, 0]
(1..row).each do |i|
  (1..col).each do |j|
      puts (0..8).reduce(0) { |sum, k| sum + grid[i + dx[k]][j + dy[k]]}
end

您可以将邻居的枚举移动到单独的方法中:

def each_neighbor(x, y)
  raise IndexError unless within_bounds?(x, y)
  return enum_for(:each_neighbor, x, y) unless block_given?
  (y - 1).upto(y + 1) do |j|
    (x - 1).upto(x + 1) do |i|
      next unless within_bounds?(i, j)  # skip out of bounds cells
      next if i == x && j == y          # skip middle cell
      yield grid[i][j]
    end
  end
end
给定坐标
x
y
此代码将简单地生成(有效)邻居。如果没有给出块,第一行返回一个枚举数

除了嵌套循环,您还可以利用来生成偏移:

[-1, 0, 1].repeated_permutation(2) do |dx, dy|
  next unless within_bounds?(x + dx, y + dy)
  next if dx.zero? && dy.zero? # skip middle cell
  yield grid[x + dx][y + dy]
end
但是,更重要的是,返回枚举数允许您从以下位置链接方法:


您可以将邻居的枚举移动到单独的方法中:

def each_neighbor(x, y)
  raise IndexError unless within_bounds?(x, y)
  return enum_for(:each_neighbor, x, y) unless block_given?
  (y - 1).upto(y + 1) do |j|
    (x - 1).upto(x + 1) do |i|
      next unless within_bounds?(i, j)  # skip out of bounds cells
      next if i == x && j == y          # skip middle cell
      yield grid[i][j]
    end
  end
end
给定坐标
x
y
此代码将简单地生成(有效)邻居。如果没有给出块,第一行返回一个枚举数

除了嵌套循环,您还可以利用来生成偏移:

[-1, 0, 1].repeated_permutation(2) do |dx, dy|
  next unless within_bounds?(x + dx, y + dy)
  next if dx.zero? && dy.zero? # skip middle cell
  yield grid[x + dx][y + dy]
end
但是,更重要的是,返回枚举数允许您从以下位置链接方法:


谢谢我得到了,并期望生成零值,因为它是。关于如何有效地排除任何超出边界的坐标,有什么建议吗?@JeremyFlagan:是的,一些if可以很好地完成这项工作。@JeremyFlagan:这是我多年前编写的一个生活游戏。因此,无需对代码进行判断:)您可以通过使用散列而不是数组来避免边界检查<代码>网格[1][2]
将变成
网格[[1,2]]
。您甚至可以给散列一个默认值
0
@Stefan:或将单元格访问封装在一个方法中(该方法将包含适当的保护和默认值):
get\u cell(1,2)
谢谢。我得到了,并期望生成零值,因为它是。关于如何有效地排除任何超出边界的坐标,有什么建议吗?@JeremyFlagan:是的,一些if可以很好地完成这项工作。@JeremyFlagan:这是我多年前编写的一个生活游戏。因此,无需对代码进行判断:)您可以通过使用散列而不是数组来避免边界检查<代码>网格[1][2]
将变成
网格[[1,2]]
。你甚至可以给散列一个默认值
0
@Stefan:或者将单元格访问封装在一个方法中(该方法将包含适当的保护和默认值):
get_cell(1,2)
如果要使用填充,则必须在字段的所有边添加它,不?@SergioTulentsev感谢先生指出这一点,很好的捕获,编辑了答案。如果要使用填充,则必须在字段的各个面添加填充,否?@SergioTulentsev感谢先生指出这一点,好的,编辑了答案。