Arrays 什么';使用while循环构造Ruby数组最干净的方法是什么?

Arrays 什么';使用while循环构造Ruby数组最干净的方法是什么?,arrays,ruby,Arrays,Ruby,Ruby有很多很好的迭代和直接返回结果的方法。这主要涉及数组方法。例如: def ten_times_tables (1..5).map { |i| i * 10 } end ten_times_tables # => [10, 20, 30, 40, 50] 但是,有时我想在时使用进行迭代,并直接返回结果数组。例如,数组的内容可能取决于预期的最终值或某些累加器,甚至取决于我们无法控制的条件 (人为的)示例可能如下所示: def fibonacci_up_to(max_number

Ruby有很多很好的迭代和直接返回结果的方法。这主要涉及数组方法。例如:

def ten_times_tables
  (1..5).map { |i| i * 10 }
end

ten_times_tables # => [10, 20, 30, 40, 50]
但是,有时我想在时使用
进行迭代,并直接返回结果数组。例如,数组的内容可能取决于预期的最终值或某些累加器,甚至取决于我们无法控制的条件

(人为的)示例可能如下所示:

def fibonacci_up_to(max_number)
  sequence = [1, 1]

  while sequence.last < max_number
    sequence << sequence[-2..-1].reduce(:+)
  end

  sequence
end

fibonacci_up_to(5) # => [1, 1, 2, 3, 5]

其他人对这类问题有更聪明的解决方案吗?

对于这种情况,您可能想要研究的东西(尽管您的人为示例可能比您的实际用例更适合这一点)正在创建一个,因此您的人为示例变成:

从用于初始化的文档中:

fib=Enumerator.new do|y|
a=b=1
环道

y与Simple Lime的枚举器解决方案类似,您可以编写一个将自身包装在枚举器中的方法:

def fibonacci_up_to(max_number)
  return enum_for(__callee__, max_number) unless block_given?

  a = b = 1
  while a <= max_number
    yield a
    a, b = b, a + b
  end
end

fibonacci_up_to(5).to_a # => [1, 1, 2, 3, 5]

正如你所说,你的人为设想是很不寻常的。因此,实现结果的代码看起来也有点不寻常。但我看不出你最初的方法有什么特别的错误,也没有任何显著的改进方法。
fib = Enumerator.new do |y|
  a = b = 1
  loop do
    y << a
    a, b = b, a + b
  end
end
p fib.take_while { |elem| elem <= 5 }
#=> [1, 1, 2, 3, 5]
def fibonacci_up_to(max_number)
  return enum_for(__callee__, max_number) unless block_given?

  a = b = 1
  while a <= max_number
    yield a
    a, b = b, a + b
  end
end

fibonacci_up_to(5).to_a # => [1, 1, 2, 3, 5]
fibonacci_up_to(5) do |i|
  # ..
end