how to stream a collection backwards without copies?

萝らか妹 提交于 2019-12-07 06:24:19

问题


I would like to know how to stream a collection backwards without copies in Pharo/Squeak.

For example, to stream #(1 2 3) so stream next returns 3, then 2, then 1. I know I could just use collection reversed readStream, but reversed copies.


回答1:


You could use a Generator:

| coll stream |
coll := #(1 2 3).
stream := Generator on: [:g | coll reverseDo: [:ea | g yield: ea]].
stream next

Generators let you wrap a streaming interface around any piece of code, basically.




回答2:


Create the RevertingCollection class as a subclass of SequeanceableCollection with one instance variable collection. Now define these three methods (instance side):

on: aCollection
    collection := aCollection

size
    ^collection size

at: index
    ^collection at: self size - index + 1

Done. You can now do the following:

stream := (RevertingCollection new on: #(1 2 3)) readStream.

and you will get

stream next "3".
stream next "2".
stream next "1"

You can go a step further and implement the message

SequenceableCollection >> #reverseStream
    ^(RevertingCollection new on: self) readStream

In this way everything reduces to just

#(1 2 3) reverseStream

ADDENDUM

As discussed in the comments there are two pieces missing here which are:

1. An instance creation method (class side)

RevertingCollection class >> #on: aCollection
    ^self new on: aCollection

With this addition the method above should be rewritten to:

SequenceableCollection >> #reverseStream
    ^(RevertingCollection on: self) readStream

Note: Other smalltalkers would prefer this method to be named #withAll:.

2. The following method for copying:

RevertingCollection >> #copyFrom: start to: stop
    | n |
    n := self size.
    copy := collection copyFrom: n - stop + 1 to: n - start + 1.
    ^self class on: copy

This method is required to support #next: in the reverse read stream.




回答3:


There are three options off the top of my head:

  1. Modify your code to use #reverseDo:
  2. Use Xtreams
  3. Roll your own stream


来源:https://stackoverflow.com/questions/29177818/how-to-stream-a-collection-backwards-without-copies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!