Iterator.st
author claus
Sat, 18 Feb 1995 00:50:56 +0100
changeset 62 a759b5c72c98
child 290 f4fbe0881e1b
permissions -rw-r--r--
Initial revision

"       NAME            Iterator
        AUTHOR          miw@cs.man.ac.uk (Mario Wolczko)
        FUNCTION        a wrapper for blocks that iterate over collections
        ST-VERSION      4.0 4.1
        PREREQUISITES   
        CONFLICTS
        DISTRIBUTION    world
        VERSION         1
        DATE    18 Jun 1991
        SUMMARY
 Occasionally you may have a block that when evaluated can be
treated as a collection -- ie it takes another block as parameter,
then applies that to a sequence of values.

This goodie wraps the block into an object -- an iterator -- which is
part of the collection hierarchy, and therefore inherits a variety of
useful collection-related methods.

Mario Wolczko

Dept. of Computer Science   Internet:      mario@cs.man.ac.uk
The University              uucp:        uknet!!man.cs!!mario
Manchester M13 9PL          JANET:         mario@uk.ac.man.cs
U.K.                        Tel: +44-61-275 6146  (FAX: 6236)
______the mushroom project___________________________________

"
'From Objectworks(r)\Smalltalk, Release 4 of 25 October 1990 on 18 June 1991 at 7:48:59 pm'!

Collection subclass: #Iterator
        instanceVariableNames: 'block '
        classVariableNames: ''
        poolDictionaries: ''
        category: 'Collections-Sequenceable'
!

Iterator comment:
'An Iterator is a read-only collection that evaluates a block to yield the elements
 of the collection.'
!

!Iterator methodsFor: 'removing'!

remove: oldObject ifAbsent: anExceptionBlock 
        "Iterators are read-only."
        self shouldNotImplement
! !

!Iterator methodsFor: 'adding'!

add: anObject
        "Iterators are read-only"
        self shouldNotImplement
! !

!Iterator methodsFor: 'enumerating'!

do: aBlock
        block value: aBlock
!

findFirst: aBlock
        "Answer the index of the first element of the receiver
        for which aBlock evaluates as true."

        | index |
        index := 1.
        self do: [ :el | (aBlock value: el) ifTrue: [^index].  index := index + 1].

        ^0
!

findLast: aBlock
        "Answer the index of the last element of the receiver
        for which aBlock evaluates as true."

        | index last |
        index := 1.
        last := 0.
        self do: [ :el | (aBlock value: el) ifTrue: [last := index].  index := index + 1].
        ^last
!

keysAndValuesDo: aBlock  
        "Evaluate aBlock with each of the receiver's key/value pairs
        (e.g. indexes and elements) as the arguments."

        | index |
        index := 1.
        self do: [:el | aBlock value: index value: el.  index := index + 1]
! !

!Iterator methodsFor: 'accessing'!

identityIndexOf: anElement 
        "Answer the identity index of anElement within the receiver.  
         If the receiver does not contain anElement, answer 0."

        ^self identityIndexOf: anElement ifAbsent: [0]
!

identityIndexOf: anElement ifAbsent: exceptionBlock 
        "Answer the identity index of anElement within the receiver.  
         If the receiver does not contain anElement, answer the result 
         of evaluating the exceptionBlock."

        | index |
        index := 1.
        self do: [ :el | el == anElement ifTrue: [^index].  index := index + 1].
        ^exceptionBlock value
!

indexOf: anElement 
        "Answer the index of anElement within the receiver.  If the receiver does
        not contain anElement, answer 0."

        ^self indexOf: anElement ifAbsent: [0]
!

indexOf: anElement ifAbsent: exceptionBlock 
        "Answer the index of anElement within the receiver.  If the receiver does
        not contain anElement, answer the result of evaluating the exceptionBlock."


        | index |
        index := 1.
        self do: [ :el | el = anElement ifTrue: [^index].  index := index + 1].
        ^exceptionBlock value
! !

!Iterator methodsFor: 'private'!

block: aBlock
        block := aBlock
!

species
        ^OrderedCollection
! !

!Iterator methodsFor: 'converting'!

asOrderedCollection
        "Answer a new instance of OrderedCollection whose elements are the elements of
        the receiver.  The order in which elements are added depends on the order in
        which the receiver enumerates its elements.  In the case of unordered collections,
        the ordering is not necessarily the same for multiple requests for the conversion."


        | anOrderedCollection |
        anOrderedCollection := OrderedCollection new.
        self do: [:each | anOrderedCollection addLast: each].
        ^anOrderedCollection
! !

!Iterator class methodsFor: 'instance creation'!

on: aBlock
        ^self new block: aBlock
!

on: collection msg: msg
        ^self new block: [ :aBlock | collection perform: msg with: aBlock]
! !

"COPYRIGHT.
 The above file is a Manchester Goodie protected by copyright.
 These conditions are imposed on the whole Goodie, and on any significant
 part of it which is separately transmitted or stored:
        * You must ensure that every copy includes this notice, and that
          source and author(s) of the material are acknowledged.
        * These conditions must be imposed on anyone who receives a copy.
        * The material shall not be used for commercial gain without the prior
          written consent of the author(s).
 Further information on the copyright conditions may be obtained by
 sending electronic mail:
        To: goodies-lib@cs.man.ac.uk
        Subject: copyright
 or by writing to The Smalltalk Goodies Library Manager, Dept of
 Computer Science, The University, Manchester M13 9PL, UK

 (C) Copyright 1992 University of Manchester
 For more information about the Manchester Goodies Library (from which 
 this file was distributed) send e-mail:
        To: goodies-lib@cs.man.ac.uk
        Subject: help 
"!