3

Ruby で私が気に入っているのは、その優雅さです。injectorを and とmap一緒に使用するtake_whileselect、ブロックを連鎖させて、ほとんど書かなくても多くのことを達成できます。

単一行ソリューションのアイデアに固執すると、ネストされたループ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-inループeach()は の右側のオブジェクトを呼び出すため、ルビストはループをin使用しません。オブジェクトを直接呼び出します。for-ineach()

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 stdlib の一部であり、本格的な Ruby スピーカーはそのインターフェイスを学ぶ必要があります。

于 2013-07-09T06:38:23.617 に答える