0

当我遍历一个数组时

@arr.each {|x|
  x.increment #x is an instance of my class that implements the increment method
  if !array_valid? #array_valid? is my method with specific logic
     #make 'x' previous item in array and continue
  end
}

是否可以返回上一个项目而不是继续以下项目?这样,当前项目将再次循环,直到!array_valid?为假。

例如,假设当前 x 在数组中的索引 5 处,!array_valid?为真,所以循环返回到索引 4,在那里增加一个值,!array_valid?为假,下一个索引为 5,!array_valid?为假,下一个索引是 6,...,直到数组的末尾。

或者 Ruby 中是否有任何其他循环可以轻松实现这种行为?

4

2 回答 2

1

你应该能够做到这一点,使用数组索引:

i = 0
while ( x = @arr[i] ) do
  x.increment
  if array_valid?
    i += 1 
  else
    i -= 1
  end
end

如果你有一个复杂的规则来遍历一个结构,有时回退到索引操作会更简单,但并不总是有一种聪明的 Ruby 风格的方法来抽象它。虽然在这种情况下可能有一种方法可以在循环中操纵迭代器,但.each我还没有检查以排除它。

于 2013-11-02T15:03:42.937 回答
0

我查看了您引用的“简单 [Sudoko] 求解算法” 。仔细听,你会听到它在低语,“使用递归!使用递归!”。您可能想尝试这样的事情(有些是伪代码)或在将来遇到类似问题时考虑使用递归:

def solve_it
  initial_state = < [], {}, nil or ? >
  outcome, solution = solve_next([0,0], initial_state)
  if outcome == :solved
    puts "I solved it! I solved it!"
    puts "Here's my solution!"
    <print solution>
  else
    puts "No solution exists"    
  end
end

def solve_next(current_cell, state)
  (1..9).each do |v|
    if current_cell -> v is valid
      new_state = state + current_cell -> v
      (return :solved, new_state) if current_cell == last_cell ([nrows-1, ncols-1])
      i, j = current_cell
      new_current_cell = (j < ncols-1) ? [i,j+1] : [i+1, 0]
      outcome, solution = solve_next(new_current_cell, new_state)
      if outcome == :solved
        updated_solution = solution + current_cell -> v
        return :solved, updated_solution
      end
    end
  end   
  return :no_solution
end          
于 2013-11-02T17:32:05.473 回答