2

次の配列があるとしましょう。

my_array = [1, 5, 8, 11, -6]

この配列を繰り返し処理し、現在の値の前の値を一緒に追加する必要があります。例はおそらく理解しやすいでしょう。次のような配列を返す必要があります。

final_array = [1, 6, 14, 25, 19]

私はこのようなことをしようとしました:

my_array.collect {|value| value + previous_values }

しかし、配列内の以前の値を取得する方法がわからないため、明らかにそれは機能しません。

私はプログラミング初心者なので、これは私が作っているよりも簡単かもしれません。収集または注入のいずれかを使用する必要があることはかなり確信していますが、これを行う方法がわからないようです。

どんな助けでもいただければ幸いです。

4

6 に答える 6

9

私の最初の本能は次のとおりでした:「それは明らかにスキャン(別名prefix-sum)なので、簡単なはずです」:

[1, 5, 8, 11, -6].scan(:+)

明らかに、 RubyにはないEnumerable#scanので、私は最近HaskellとScalaを読みすぎています…まだ:

module Enumerable
  def scan(initial=first, &block)
    [initial].tap {|res| 
      reduce {|acc, el| 
        block.(acc, el).tap {|el|
          res << el
        }
      }
    }
  end
end

Enumerable#scanのように動作する場合、Enumerable#reduceつまり、オプションの初期引数とオプションのシンボルを使用する場合は、Rubiniusから盗まれた引数マッサージコードを使用してバージョンを少し拡張する必要がありますEnumerable#reduce

module Enumerable
  def scan(initial=nil, sym=nil, &block)
    args = if initial then [initial] else [] end
    unless block_given?
      args, sym, initial = [], initial, first unless sym
      block = ->(acc, el) { acc.send(sym, el) }
    end
    [initial || first].tap {|res| 
      reduce(*args) {|acc, el| 
        block.(acc, el).tap {|e|
          res << e
        }
      }
    }
  end
end

この拡張バージョンでは、上記の例が機能するようになりました。

p [1, 5, 8, 11, -6].scan(:+)
# => [1, 6, 14, 25, 19]

この種の問題が再び発生する場合は、別の言語で、スキャンプレフィックス合計という用語を覚えておいてください。このような関数は通常、かなり一般的です。なぜRubyにまだそれらがないのかよくわかりません。

于 2010-05-17T09:51:40.397 に答える
6

あなた自身の試みcollectはすでに非常に近かった。前の値を合計し続けてください。

my_array = [1, 5, 8, 11, -6]
previous_values = 0
my_array.collect { |value| previous_values += value }
# => [1, 6, 14, 25, 19]
于 2010-05-17T08:48:16.820 に答える
3
x = 0
[1, 5, 8, 11, -6].map {|a| x = x +a }
于 2010-05-17T08:18:44.493 に答える
1
my_array.each_index{|i| my_array[i] += my_array[i-1] if i>0 }

また

my_array.inject([]){|memo, item| memo << item + memo.last.to_i }
于 2010-05-17T08:16:34.977 に答える
1

あなたはこれを使うことができます:

my_array = [1, 5, 8, 11, -6]
final_array = []

my_array.inject(0) {|res, it| final_array << res + it; res + it}
于 2010-05-17T08:26:37.110 に答える
1

結果の配列を事前に割り当てるためのgemを作成しました。多数の要素を持つEnumerableの場合でも、操作は非常に高速です。Enumerable#mapを使用するソリューションとは異なり、構文はEnumerable#reduceの構文とまったく同じであり、モンキーパッチを適用した#reduceがある場合は、オプションでEnumerable#reduceを内部で使用できます。この名前は、同じ名前のClojureの機能から取られました。

https://rubygems.org/gems/reductions

インストールするには:

$ gem install reductions

使用するには:

require 'reductions'

[1, 5, 8, 11, -6].reductions(:+)            #=> [1, 6, 14, 25, 19]
[1, 5, 8, 11, -6].reductions{|a| a + b}     #=> [1, 6, 14, 25, 19]

# With an inital value:
[1, 5, 8, 11, -6].reductions(1,:+)          #=> [1, 2, 7, 15, 26, 20]
[1, 5, 8, 11, -6].reductions(1){|a| a + b}  #=> [1, 2, 7, 15, 26, 20]
于 2015-03-19T22:11:11.223 に答える