From: keiju@... (=?ISO-2022-JP?B?GyRCQFBETTc9PHkbKEI=?=) Date: 2009-08-04T19:43:15+09:00 Subject: [ruby-dev:39008] Re: Enumerator#peek けいじゅ@いしつかです. In [ruby-dev:38973] the message: "[ruby-dev:38973] Re: Enumerator#peek", on Aug/01 01:54(JST) Tanaka Akira writes: >ソート済みのを複数マージするというのは、内部イテレータではで >きないので、やっぱり外部イテレータを使うことになります。 確かに内部処理はそうなっています. >この場合 peek は... マージの途中で中断したときに要素が蒸発し >てしまわないようにするのに利用できますね。まぁ、すごく役に立 >つというほどではありませんが。 それでも, n個のマージだとアルゴリズムが結構きれいになります. だんだん, peekが欲しくなってきた(^^;; >あと、2個じゃなくて一般に n個をマージ、とか考えると、まず優 >先順位つきキューが欲しいですよねぇ。なんで標準添付されていな >いんだろう。 これも欲しいかも(^^;; >> 私もそう思っています. それに, threadをまたげないので, 複数スレッドにま >> たがるqueue見たいのも実現できないですし... > >あぁ、thread のことは気がついていませんでした。そういう利点 >もありますね。 外部イテレータと内部イテレータの違いはブロックの境界を越えられるかどう かなんですが, 今のEnumeratorの仕様だとメソッド内で局所的に使うなら(ス レッドを把握できるので)まだよいですが, メソッドをまたがったりすると使 えない感じなんですよねぇ.... >> Arrayなんかは, 上記の Enumerator.external_iterator みたいな, やり方で >> は実現できそうもない(fiber使えば別ですが(^^;;)ので別途対処が必要ですね. > >たとえば配列なら、 > > i = -1 > Enumerator.external_iterator { > i += 1 > raise StopIteration if ary.length <= i > ary[i] > } > >というようにできます。 おー. 気が付かなかった... あ, でも, これは配列がインデックスアクセス可能だからですね. hashは無理 かも... でも, 1.9のHashは内部で順序を維持しているからインデックスアク セスを許すようにすれば可能な気がしますね. >まぁ、rewind や marshal をどうするかとか、each を呼んだらど >うするかとか、あまり完全とはいえないのも事実ではあるのです >が、うまくいくデザインも可能だろう、と思っています。 インデックスアクセス可能ならば大丈夫な気がします. そうすると, かなりのEnumerableな組み込みクラスの関してはEnumeratorにで きそうですね. >> a.inject_by(proc{|w| w}){|key, sum, value| sum += 1}.each{|key,sum| puts "#{key} #{sum}"} >えーと、ブロックの中を sum += 1 としてしまったので、 >inject_by はそうはできなくなっている、と思うんですがどうでしょ >う。 > >sum += 1 というブロックを使って sum1 + sum2 という足し算を行 >うのは無理っぽいですよね。 なかなか鋭いですね(^^;;; また間違えてしまいました. この場合: a.inject_by(proc{|w| w}){|key, sum, value| sum + 1}.each{|key,sum| puts "#{key} #{sum}"} でした. あ. でも, これだと結合律成り立たないですし, グループ毎の小計と かもとれないんですね... fairyだと, key, valueの区別がないのですが,総和 をとったりするにはvalue部を取り出せないとまずいなぁ... こんな感じにな りますか... a.inject_by(proc{|w| w}, :value => proc{|w| 1}){|key, sum, value| sum + value}.each{|key,sum| puts "#{key} #{sum}"} >> あー. inject ってそんなイメージあります? いちおう, reduceという名前も >> aliasしていますが, Rubyのinjectと似ているので同じ名前にしました. > >inject という名前は Ruby でしか経験がないので、偏ってるかも >しれません。 inject って Smalltalkから来たんだと思いますが, 数値のならびの間に演算 子を中にいれるってところから来ているのかな? と考えています. ですので, それに結合律を前提としてもまあよいんじゃないかと考えたわけです. >> なんだか, slice_byは結構使えるかもって気になってきました(^^;;; >> 配列はどんどん出来てしまいますけどね(^^; >配列を作ってしまって良ければ、できます。 >peek の意図は、それを避けたいという話です。 なるほど. >> slice_byを Ruby(のスクリプト)で実現したければ peekもしくはpeekと同じ処 >> 理が必要になりますね. ---(1) > >いや、slice_by は内部イテレータで実装します。外部イテレータ >は使いませんので、peek も使いません。内部イテレータを使うと >きでも先読みを行う (というか、処理を一巡遅延させる)、という >意味でしたらそのとおりですが。 それが, 後半のpeekと同じ処理の意味のつもりでした. __ ---------------------------------------------------->> 石塚 圭樹 <<--- ---------------------------------->> e-mail: keiju@ishitsuka.com <<---