3

我喜欢 Ruby 的一点是它的优雅:如果我们将injectormaptake_whileand一起使用select,我们可以将块链接在一起,从而在编写少量代码的同时实现很多目标。

坚持单行解决方案的想法,如何for在 Ruby 中编写嵌套循环而不编写整个嵌套for循环?我觉得这一定是可能的,我只是无法为我的生活弄清楚它是什么。我正在寻找这样的东西:

10.times {|a| 10.times {|b| a*b}}

我能想出的唯一优雅的解决方案是嵌套for循环。有没有人有更好的解决方案?

array = []
for a in (1..10)
  for b in (1..10)
    array << a*b
  end
end
4

7 回答 7

7

Array 有一些很酷的方法。

 Array(1..10).repeated_permutation(2).map {|a, b| a*b }

#repeated_permutation将获取一个数组并生成该数组的所有排列的数组,该数组具有给定长度(在本例中为 2),允许重复(即[1,1])。然后,我们可以将每对的乘积映射到最终数组中。

您可以使用inject(:*). 这将采用结果排列并将每个元素的所有元素相乘。例如,要生成(1*1*1*1)..(10*10*10*10)(产生 10,000 个元素的输出集!):

Array(1..10).repeated_permutation(4).map {|v| v.inject :*}
于 2013-07-09T04:42:16.693 回答
4
(1..10).to_a.product((1..10).to_a).map { |a,b| a*b }

http://ruby-doc.org/core-2.0/Array.html#method-i-product

于 2013-07-09T04:08:55.007 回答
3

我能想出的唯一优雅的解决方案是嵌套 for 循环

for-in循环调用each()右边的对象in,所以 ruby​​ists 不使用for-in循环——他们each()直接调用对象:

array = []

(1..10).each do |a|
  (1..3).each do |b|
    array << a*b
  end
end

坚持单线解决方案的理念

这样做几乎可以保证您不会编写优雅的 ruby​​ 代码——只需查看建议的解决方案即可。

于 2013-07-09T08:50:09.037 回答
2
arr = (1..10).map {|a| (1..10).map {|b| a*b}}.flatten
于 2013-07-09T04:06:52.323 回答
1

for看看这个问题的所有答案,我觉得没有一个比 OP 的嵌套循环更“优雅”或更容易阅读。如果您想要一个不那么冗长的嵌套迭代符号,我认为您不会比定义自己的速记更好。就像是:

 module Enumerable
   def combinations(*others)
     return enum_for(:combinations,*others) if not block_given?
     return if self.empty?
     if others.empty?
       self.each { |x| yield [x] }
     else
       others.first.combinations(*others.drop(1)) { |a| self.each { |x| yield (a + [x]) }}
     end
   end
 end

定义了此实用程序方法后,您可以将嵌套迭代的示例编写为:

array = []
(1..10).combinations(1..10) { |a,b| array << a*b }
于 2013-07-09T06:59:15.673 回答
0
(1..10).inject([]) { |result,a| result + (1..10).to_a.map { |b| a*b } }

或者

def arithmetic(range, &block)
  range.inject([]) { |result,a| result + range.to_a.map { |b| block.call(a,b) } }
end

range = (1..10)
arithmetic(range) {|a,b| a*b }
arithmetic(range) {|a,b| a+b }
于 2013-07-09T04:43:01.760 回答
0

面对这样的问题,记住你的高中微积分:

a = *1..10
b = *1..10
require 'matrix'

Matrix.column_vector( a ) * Matrix[ b ]
# or equivalent
Matrix[ a ].transpose * Matrix[ b ]

Matrix 是 Ruby 标准库的一部分,每个认真的 Ruby 演讲者都应该学习它的接口。

于 2013-07-09T06:38:23.617 回答