1

Rubyでの位置によって2D配列のすべての要素を追加する最も明確で効率的な方法は何ですか? 例:

2darray = [[1,2,3],[1,2,3]]
result = [2,4,6]

次のコードがあります

def sum_elements_by_position(array)
 total_elements = array.length
 result = []

 for i in 0...array.first.length
   n = 0
   array.each { |subarray| n += subarray[i] }
   result << n
 end
 result
end

前提: すべての主要な要素は同じ長さです

ボーナス ポイントについては、任意の長さの主要な要素を機能させるソリューションを確認することは素晴らしいことです

4

3 に答える 3

3

zip最初の行と残りの行を合計してから、次のようにします。

def sum_elements_by_position(array)
    array[0].zip(*array[1..-1]).map do |col|
        col.inject(:+)
    end
end
于 2012-12-18T00:30:32.733 に答える
0

行が同じ長さでない場合に対処するソリューションを次に示します。

def sum_cols arr
  arr.reduce( [] ) do |res,row| 
    row.each_with_index { |e,i| res[i] ||= 0; res[i] += e }
    res
  end
end

irb> sum_cols [ [0,1,2], [3,4], [5,6,7,8] ]
=> [8, 11, 9, 8]

@oldergodは、最長の行に基づいてzipを使用することを提案しましたが、最長の行を見つけてnilsを拒否するにはコストがかかります。上記の配列例を使用して、上記のメソッドに対して以下のベンチマークを行い、reduce + each_with_indexメソッドが30%以上高速であることがわかりました。

def sum_cols_using_zip arr
  max_len = arr.map(&:size).max
  ([0] * max_len).zip(*arr).map do |col|
    col.compact.inject(:+)
  end
end
于 2012-12-18T07:31:46.077 に答える
0

私はこれをします:

a.transpose.map {|x| x.reduce(:+)}

クリーン、シンプル、柔軟。.transposeターンはこれ

[[1,2,3,4],[2,3,4,5],[3,4,5,6]]

これに

[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]

次に、各サブアレイに.map適用されます。.reduce次に、.reduceサブ値を追加して集計します。または、より正確には、+メソッドをそれらに適用することによって。

この例を完全に理解するまで、これらの関数のドキュメントを読むことを強くお勧めします。これは、Ruby の考え方を簡潔に示した非常に優れたデモンストレーションです。

于 2013-01-05T04:43:36.710 に答える