From: matz@... (Yukihiro Matsumoto) Date: 2002-11-09T10:38:48+09:00 Subject: [ruby-dev:18713] Re: Enumerable#zip まつもと ゆきひろです In message "[ruby-dev:18696] Re: Enumerable#zip" on 02/11/08, Shin-ichiro HARA writes: |In [ruby-dev:18692] Re: Enumerable#zip | Tanaka Akira writes: | | >ふと思ったんですが、Enumerable.zip(a, b, c, ...) はどうでしょう? | >同じかなぁ。 | |相変わらず不揃いなデータへの対応の問題は残りますが、それもあり得ますよ |ね。でもそうすると、a, b, c, ... に Array でなくて、Enumerable を入れ |たくなりません?そしてそれなら、Enumerable.map(a, b, c, ...) という名 |前でいいし、同様に Enumerable.each(a, b, c, ...) などのイテレータも考 |えられる。だだし、この「平行 each 系」というのは、今までの Ruby の雰囲 |気から逸脱したところがあるのですが。 そうですね。threadやcontinuationを使えばEnumerableでも並行 eachができますが(添付)。 | >> 後者が好きではないのは、「Array の各要素が Array であることを仮定する | >> メソッドを Array に作り込むのが気持ち悪い」ということですかね。つまり、 | >> そんなふうに「タイプ X 上の Array」に対する Array のメソッドを作って行っ | >> たらきりがない、ということでしょうか? | > | >まぁ、すでに assoc なんてのもありますけどね。 | |そうですね。だから、配列の配列に限って、若干サービスを拡大してもいいん |じゃないかと思った訳です。 どっちかっていうと見かけが悪いってところじゃないでしょうか。 --- 添付: generator.rb class Generator def initialize(method, *args) @cont_l = nil method.call(*args) {|v| callcc {|c| @cont_i = c @value = v return unless @cont_l @cont_l.call } } @cont_i = nil @cont_l.call end def next unless @cont_i raise "no more element" end v = @value callcc{|cc| @cont_l = cc @cont_i.call } v end def more? if @cont_i then true else false end end end class Object def generator(method, *args) Generator.new(self.method(method), *args) end end if $0 == __FILE__ def zip(*args) generators = args.collect{|x| x.generator(:each)} ary = [] while generators.any?{|x| x.more?} ary.push(generators.collect{|x| x.next rescue nil}) end ary end a = 1..10 b = "a".."z" for x,y in zip(a,b) p [x,y] end end