在ruby中迭代多个数组的优雅和简洁方法是什么?

时间:2013-07-09 04:02:54

标签: ruby loops

我喜欢Ruby的优点是:如果我们使用injectmap以及take_whileselect,我们可以将块链接在一起以实现很多目标虽然写得很少。

坚持单行解决方案的思想,如何在Ruby中编写嵌套的for循环而不编写整个嵌套的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

7 个答案:

答案 0 :(得分: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 :*}

答案 1 :(得分: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

答案 2 :(得分:3)

  

我能想到的唯一解决方案就是嵌套for循环

for-in循环在each()右侧的对象上调用in,因此rubyists不使用for-in循环 - 他们直接调用each()在对象上:

array = []

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

坚持单线解决方案的想法

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

答案 3 :(得分:2)

arr = (1..10).map {|a| (1..10).map {|b| a*b}}.flatten

答案 4 :(得分:1)

看看这个问题的所有答案,我觉得它们中的任何一个看起来都不比OP的嵌套for循环更“优雅”或更容易阅读。如果你想要一个不那么详细的嵌套迭代表示法,我认为你不会比定义自己的速记更好。类似的东西:

 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 }

答案 5 :(得分: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 }

答案 6 :(得分:0)

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

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

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

Matrix是Ruby stdlib的一部分,每个认真的Ruby演讲者都应该学习它的界面。