|
1 " |
|
2 COPYRIGHT (c) 1989-93 by Claus Gittinger |
|
3 All Rights Reserved |
|
4 |
|
5 This software is furnished under a license and may be used |
|
6 only in accordance with the terms of that license and with the |
|
7 inclusion of the above copyright notice. This software may not |
|
8 be provided or otherwise made available to, or used by, any |
|
9 other person. No title to or ownership of the software is |
|
10 hereby transferred. |
|
11 " |
|
12 |
|
13 SequenceableCollection subclass:#Interval |
|
14 instanceVariableNames:'start stop step' |
|
15 classVariableNames:'' |
|
16 poolDictionaries:'' |
|
17 category:'Collections-Sequenceable' |
|
18 ! |
|
19 |
|
20 Interval comment:' |
|
21 |
|
22 COPYRIGHT (c) 1989-93 by Claus Gittinger |
|
23 All Rights Reserved |
|
24 |
|
25 Intervals represent a collection (or range) of numeric values specified by |
|
26 a startValue, an endValue and a step. The elements are computed, not stored. |
|
27 For example, the interval (1 to:5) containes the elements (1 2 3 4 5) and |
|
28 (1 to:6 by:2) contains (1 3 5). |
|
29 |
|
30 |
|
31 %W% %E% |
|
32 |
|
33 written summer 89 by claus |
|
34 '! |
|
35 |
|
36 !Interval class methodsFor:'instance creation'! |
|
37 |
|
38 from:start to:stop |
|
39 "return a new interval with elements from start |
|
40 to stop by 1" |
|
41 |
|
42 ^ self new |
|
43 setFrom:start |
|
44 to:stop |
|
45 by:1 |
|
46 ! |
|
47 |
|
48 from:start to:stop by:step |
|
49 "return a new interval with elements from start |
|
50 to stop by step" |
|
51 |
|
52 ^ self new |
|
53 setFrom:start |
|
54 to:stop |
|
55 by:step |
|
56 ! ! |
|
57 |
|
58 !Interval methodsFor:'private'! |
|
59 |
|
60 setFrom:startInteger to:stopInteger by:stepInteger |
|
61 start := startInteger. |
|
62 stop := stopInteger. |
|
63 step := stepInteger |
|
64 ! ! |
|
65 |
|
66 !Interval methodsFor:'accessing'! |
|
67 |
|
68 first |
|
69 "return the first element of the collection" |
|
70 |
|
71 ^ start |
|
72 ! |
|
73 |
|
74 start |
|
75 "return the first number of the range" |
|
76 |
|
77 ^ start |
|
78 ! |
|
79 |
|
80 start:aNumber |
|
81 "set the first number of the range" |
|
82 |
|
83 start := aNumber |
|
84 ! |
|
85 |
|
86 stop |
|
87 "return the end number of the range" |
|
88 |
|
89 ^ stop |
|
90 ! |
|
91 |
|
92 stop:aNumber |
|
93 "set the end number of the range" |
|
94 |
|
95 stop := aNumber |
|
96 ! |
|
97 |
|
98 step |
|
99 "return the step increment of the range" |
|
100 |
|
101 ^ step |
|
102 ! |
|
103 |
|
104 step:aNumber |
|
105 "set the step increment of the range" |
|
106 |
|
107 step := aNumber |
|
108 ! |
|
109 |
|
110 size |
|
111 "return the number of elements in the collection" |
|
112 |
|
113 (step < 0) ifTrue:[ |
|
114 (start < stop) ifTrue:[ |
|
115 ^ 0 |
|
116 ]. |
|
117 ^ stop - start // step + 1 |
|
118 ]. |
|
119 (stop < start) ifTrue:[ |
|
120 ^ 0 |
|
121 ]. |
|
122 ^ stop - start // step + 1 |
|
123 ! |
|
124 |
|
125 at:index |
|
126 (index between:1 and:self size) ifTrue:[ |
|
127 ^ start + (step * (index - 1)) |
|
128 ]. |
|
129 self errorSubscriptBounds:index |
|
130 ! |
|
131 |
|
132 at:index put:anObject |
|
133 self error:'you cannot store into an interval' |
|
134 ! ! |
|
135 |
|
136 !Interval methodsFor:'adding/removing elements'! |
|
137 |
|
138 add:newObject |
|
139 self error:'elements cannot be added to an interval' |
|
140 ! |
|
141 |
|
142 remove:anObject |
|
143 self error:'elements cannot be removed from an interval' |
|
144 ! ! |
|
145 |
|
146 !Interval methodsFor:'private'! |
|
147 |
|
148 species |
|
149 ^ OrderedCollection |
|
150 ! ! |
|
151 |
|
152 !Interval methodsFor:'enumeration'! |
|
153 |
|
154 do:aBlock |
|
155 |aValue| |
|
156 |
|
157 aValue := start. |
|
158 step < 0 ifTrue:[ |
|
159 [stop <= aValue] whileTrue:[ |
|
160 aBlock value:aValue. |
|
161 aValue := aValue + step |
|
162 ] |
|
163 ] ifFalse:[ |
|
164 [stop >= aValue] whileTrue:[ |
|
165 aBlock value:aValue. |
|
166 aValue := aValue + step |
|
167 ] |
|
168 ] |
|
169 ! |
|
170 |
|
171 select:aBlock |
|
172 "evaluate the argument, aBlock for every element in the collection |
|
173 and return a collection of all elements for which the block return |
|
174 true. redefined since SeqColl accesses the receiver with at:, which is |
|
175 slow for intervals." |
|
176 |
|
177 |newColl| |
|
178 |
|
179 newColl := OrderedCollection new:self size. |
|
180 self do:[:each | |
|
181 (aBlock value:each) ifTrue:[newColl add:each] |
|
182 ]. |
|
183 ^ newColl |
|
184 ! |
|
185 |
|
186 collect:aBlock |
|
187 "evaluate the argument, aBlock for every element in the collection |
|
188 and return a collection of the results - redefined since SeqColl |
|
189 accesses the receiver via at:, which is slow for intervals" |
|
190 |
|
191 |newCollection| |
|
192 |
|
193 newCollection := self species new:(self size). |
|
194 self do:[:each | |
|
195 newCollection add:(aBlock value:each) |
|
196 ]. |
|
197 ^ newCollection |
|
198 ! ! |