将数组中的每个元素乘以同一数组中的所有其他元素

时间:2013-12-24 20:12:33

标签: ruby arrays enums

我正在尝试在Ruby中创建一个时间表,其中给出了一个整数,输出是该整数的时间表。

示例:times_table(5)

结果:

1   2   3   4   5
2   4   6   8  10   
3   6   9  12  15   
4   8  12  16  20   
5  10  15  20  25

到目前为止,我有:

def times_table(rows)
  table_array = (1..rows).to_a

  table_array.each do |i|

end

times_table(5)

使用table_array,我可以获得[1,2,3,4,5],但我需要将结果设为1 * 2 , 1 * 3, 1 * 4, 1 * 5, 2 * 1, 2 * 2, 2 * 3等。基本上,我需要第一个元素与数组中的所有其他元素一起多个,然后移动到下一个元素。关于如何做到这一点的任何想法?

4 个答案:

答案 0 :(得分:2)

我会这样做:

def times_table(rows)
  table_rng = (1..rows)
  table_rng.each do |i|
    puts table_rng.map{|e| e*i }.join(" ")
  end
end

times_table(5)
# >> 1 2 3 4 5
# >> 2 4 6 8 10
# >> 3 6 9 12 15
# >> 4 8 12 16 20
# >> 5 10 15 20 25

更新(来自Cary Swoveland的一个很好的建议)

def times_table(rows)
  fmt = "%#{(rows*rows).to_s.size}d"
  table_rng = (1..rows)
  table_rng.each do |i|
    puts table_rng.map{|e| fmt % (e*i) }.join(' ')
  end
end

times_table(5)
# >>  1  2  3  4  5
# >>  2  4  6  8 10
# >>  3  6  9 12 15
# >>  4  8 12 16 20
# >>  5 10 15 20 25

答案 1 :(得分:2)

在数学上,我更倾向于在该用例中使用Matrix

关系是,您必须生成 n * n 矩阵,其中每个单元格具有关系(c+1) * (r+1),其中,c表示列数r表示行号(考虑0索引矩阵)

require 'matrix'
def times_table(n)
  Matrix.build(n, n) { |r, c| (c+1)*(r+1) }
end

times_table(5)
#=> Matrix[[1, 2, 3, 4, 5], [2, 4, 6, 8, 10], [3, 6, 9, 12, 15], [4, 8, 12, 16, 20], [5, 10, 15, 20, 25]]
times_table(5).to_a
#=> [[1, 2, 3, 4, 5],
 [2, 4, 6, 8, 10],
 [3, 6, 9, 12, 15],
 [4, 8, 12, 16, 20],
 [5, 10, 15, 20, 25]]

答案 2 :(得分:2)

需要ActiveSupport的另一种方法:

def times_table(n)
  [*1..n].product([*1..n]).map { |arr| arr.reduce(:*) }.in_groups(n)  
end

因此,例如,times_table(5)将返回

=> [[1, 2, 3, 4, 5],
   [2, 4, 6, 8, 10],
   [3, 6, 9, 12, 15],
   [4, 8, 12, 16, 20],
   [5, 10, 15, 20, 25]]

你可以根据自己的喜好打印它。

更新:正如Cary所指出的那样,in_groups是ActiveSupport的一部分。以上代码稍作修改,以便它可以使用标准的Ruby:

def times_table(n)
  [*1..n].product([*1..n]).map { |arr| arr.reduce(:*) }.each_slice(n).to_a  
end

你也可以这样做:

def times_table(n)
  Array.new(n) { |x| Array.new(n) { |y| (x+1)*(y+1) } }
end

答案 3 :(得分:1)

我会这样做:

def times_table(rows, spaces=1)
  fmt = "%#{(rows*rows).to_s.size}d"
  (1..rows).each {|i| \
    puts (i..i*rows).step(i).map {|j| fmt % j}.join(' '*spaces)}
end

times_table(5,2)

1   2   3   4   5
2   4   6   8  10
3   6   9  12  15
4   8  12  16  20
5  10  15  20  25  
相关问题