2016-06-29 8 views
1

This questionは、HaskellのscanlのバージョンをPythonで提供しますが、この関数のRubyバージョンはありますか?おそらく、よりよいバージョンを書くことができHaskellのscanlに相当するRubyとは何ですか?

+0

クール。これまでのあなたの質問は何ですか? – mudasobwa

+0

私はそれが助けになるなら、言い換えることができますか?私自身の関数を書かずにそれを行う方法があるのか​​、それとも関数を書くための最良の方法があるのだろうかと疑問に思った。 –

答えて

-1

が、これは私が思い付いたものです:

require 'spec_helper' 

class Array 
    def scanl accumulator, &block 
    results = [accumulator] + self 
    results.each_with_index do |e, i| 
     results[i] = block.call(accumulator, e) 
     accumulator = results[i] 
    end 
    results 
    end 
end 

describe "#scanl" do 
    it 'is similar to foldl, but returns a list of successive reduced values from the left' do 
    # example from http://learnyouahaskell.com/higher-order-functions 
    expect([3, 5, 2, 1].scanl(0, &:+)).to eq([0,3,8,10,11]) 
    end 
end 

私はもっとreduceようになり代わりにブロックの:+のように、単にメソッド名を取るためにscanlを変更すると考えました。思考?

+0

ちょっと、パイソンの質問はどうだったのか分かりませんが、私はそれを開いたままにすると私の評判を台無しにするように見えるので、私はこのポストを削除して幸せ。私の意図は、私のように、ルビーのscanlを探してcouldntを見つける次のグーグルーラーを助けることだった –

+0

ここにチャットhttp://chat.stackexchange.com/rooms/8595/the-2nd-monitor。私たちは何かを試すことができると思います –

+0

質問の質を比較するだけです。 –

1

reduce()を使用して、自分で実装することができます。

def scanl(op, init, range) 
    op = op.to_proc unless op.is_a?(Proc) 
    range.reduce([init]) { |a, e| a.push(op.call(a.last,e)) } 
end 

p scanl(lambda { |a, b| a + b }, 0, 1..10) 
#=> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55] 
p scanl(:+, 0, 1..10) 
#=> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55] 

また、map()を使用して、配列の先頭に初期要素を配置することもできます。

def scanl(op, init, range)        
    op = op.to_proc unless op.is_a?(Proc)     
    acc = init           
    range.map { |e| acc = op.call(acc, e) }.unshift(init) 
end             
+3

多くの一時配列がここにあります。 –

+0

いい感じです。私は何とか減らすことができます。あなたは 'is_a?(Proc)'チェックをしなければなりませんか?私はそれがすでにprocであって安全であれば、それはノーオペレーションであると思うだろう。 –

+1

ええ、私はそれがproc、no-opならば '.to_proc'を常に実行できることを意味する。あなたはそれをprocにしたのですか? –

関連する問題