Blame


1 8f7f2f4a 2021-12-17 jrmu ================================================================================
2 8f7f2f4a 2021-12-17 jrmu
3 8f7f2f4a 2021-12-17 jrmu Each
4 8f7f2f4a 2021-12-17 jrmu
5 8f7f2f4a 2021-12-17 jrmu each() lets you iterate through each key-value pair in a hash:
6 8f7f2f4a 2021-12-17 jrmu
7 8f7f2f4a 2021-12-17 jrmu my % = (
8 8f7f2f4a 2021-12-17 jrmu
9 8f7f2f4a 2021-12-17 jrmu );
10 8f7f2f4a 2021-12-17 jrmu my %pets = (
11 8f7f2f4a 2021-12-17 jrmu
12 8f7f2f4a 2021-12-17 jrmu fish=>3,
13 8f7f2f4a 2021-12-17 jrmu
14 8f7f2f4a 2021-12-17 jrmu cats=>2,
15 8f7f2f4a 2021-12-17 jrmu
16 8f7f2f4a 2021-12-17 jrmu dogs=>1,
17 8f7f2f4a 2021-12-17 jrmu
18 8f7f2f4a 2021-12-17 jrmu );
19 8f7f2f4a 2021-12-17 jrmu
20 8f7f2f4a 2021-12-17 jrmu while(my($pet,$qty)=each(%pets)) {
21 8f7f2f4a 2021-12-17 jrmu
22 8f7f2f4a 2021-12-17 jrmu print "pet='$pet', qty='$qty'\n";
23 8f7f2f4a 2021-12-17 jrmu
24 8f7f2f4a 2021-12-17 jrmu }
25 8f7f2f4a 2021-12-17 jrmu
26 8f7f2f4a 2021-12-17 jrmu
27 8f7f2f4a 2021-12-17 jrmu > pet='cats', qty='2'
28 8f7f2f4a 2021-12-17 jrmu
29 8f7f2f4a 2021-12-17 jrmu > pet='dogs', qty='1'
30 8f7f2f4a 2021-12-17 jrmu
31 8f7f2f4a 2021-12-17 jrmu > pet='fish', qty='3'
32 8f7f2f4a 2021-12-17 jrmu
33 8f7f2f4a 2021-12-17 jrmu
34 8f7f2f4a 2021-12-17 jrmu Every call to each() returns the next key/value pair in the hash. After
35 8f7f2f4a 2021-12-17 jrmu the last key/value pair is returned, the next call to each() will return
36 8f7f2f4a 2021-12-17 jrmu an empty list, which is boolean false. This is how the while loop is
37 8f7f2f4a 2021-12-17 jrmu able to loop through each key/value and then exit when done.
38 8f7f2f4a 2021-12-17 jrmu
39 8f7f2f4a 2021-12-17 jrmu
40 8f7f2f4a 2021-12-17 jrmu Every hash has one "each iterator" attached to it. This iterator is used
41 8f7f2f4a 2021-12-17 jrmu by perl to remember where it is in the hash for the next call to each().
42 8f7f2f4a 2021-12-17 jrmu
43 8f7f2f4a 2021-12-17 jrmu Calling keys() on the hash will reset the iterator. The list returned by
44 8f7f2f4a 2021-12-17 jrmu keys() can be discarded.
45 8f7f2f4a 2021-12-17 jrmu
46 8f7f2f4a 2021-12-17 jrmu
47 8f7f2f4a 2021-12-17 jrmu keys(%hash);
48 8f7f2f4a 2021-12-17 jrmu
49 8f7f2f4a 2021-12-17 jrmu
50 8f7f2f4a 2021-12-17 jrmu Do not add keys while iterating a hash with each().
51 8f7f2f4a 2021-12-17 jrmu
52 8f7f2f4a 2021-12-17 jrmu
53 8f7f2f4a 2021-12-17 jrmu You can delete keys while iterating a hash with each().
54 8f7f2f4a 2021-12-17 jrmu
55 8f7f2f4a 2021-12-17 jrmu
56 8f7f2f4a 2021-12-17 jrmu The each() function does not have to be used inside a while loop. This
57 8f7f2f4a 2021-12-17 jrmu example uses a subroutine to call each() once and print out the result.
58 8f7f2f4a 2021-12-17 jrmu The subroutine is called multiple times without using a while() loop.
59 8f7f2f4a 2021-12-17 jrmu
60 8f7f2f4a 2021-12-17 jrmu Calling keys() on the hash will reset the iterator. The list returned by
61 8f7f2f4a 2021-12-17 jrmu keys() can be discarded.
62 8f7f2f4a 2021-12-17 jrmu
63 8f7f2f4a 2021-12-17 jrmu
64 8f7f2f4a 2021-12-17 jrmu keys(%hash);
65 8f7f2f4a 2021-12-17 jrmu
66 8f7f2f4a 2021-12-17 jrmu
67 8f7f2f4a 2021-12-17 jrmu Do not add keys while iterating a hash with each().
68 8f7f2f4a 2021-12-17 jrmu
69 8f7f2f4a 2021-12-17 jrmu
70 8f7f2f4a 2021-12-17 jrmu You can delete keys while iterating a hash with each().
71 8f7f2f4a 2021-12-17 jrmu
72 8f7f2f4a 2021-12-17 jrmu
73 8f7f2f4a 2021-12-17 jrmu The each() function does not have to be used inside a while loop. This
74 8f7f2f4a 2021-12-17 jrmu example uses a subroutine to call each() once and print out the result.
75 8f7f2f4a 2021-12-17 jrmu The subroutine is called multiple times without using a while() loop.
76 8f7f2f4a 2021-12-17 jrmu
77 8f7f2f4a 2021-12-17 jrmu my %pets = (
78 8f7f2f4a 2021-12-17 jrmu
79 8f7f2f4a 2021-12-17 jrmu fish=>3,
80 8f7f2f4a 2021-12-17 jrmu
81 8f7f2f4a 2021-12-17 jrmu cats=>2,
82 8f7f2f4a 2021-12-17 jrmu
83 8f7f2f4a 2021-12-17 jrmu dogs=>1,
84 8f7f2f4a 2021-12-17 jrmu
85 8f7f2f4a 2021-12-17 jrmu );
86 8f7f2f4a 2021-12-17 jrmu
87 8f7f2f4a 2021-12-17 jrmu
88 8f7f2f4a 2021-12-17 jrmu sub one_time {
89 8f7f2f4a 2021-12-17 jrmu
90 8f7f2f4a 2021-12-17 jrmu my($pet,$qty)=each(%pets);
91 8f7f2f4a 2021-12-17 jrmu
92 8f7f2f4a 2021-12-17 jrmu # if key is not defined,
93 8f7f2f4a 2021-12-17 jrmu
94 8f7f2f4a 2021-12-17 jrmu # then each() must have hit end of hash
95 8f7f2f4a 2021-12-17 jrmu
96 8f7f2f4a 2021-12-17 jrmu if(defined($pet)) {
97 8f7f2f4a 2021-12-17 jrmu
98 8f7f2f4a 2021-12-17 jrmu print "pet='$pet', qty='$qty'\n";
99 8f7f2f4a 2021-12-17 jrmu
100 8f7f2f4a 2021-12-17 jrmu } else {
101 8f7f2f4a 2021-12-17 jrmu
102 8f7f2f4a 2021-12-17 jrmu print "end of hash\n";
103 8f7f2f4a 2021-12-17 jrmu
104 8f7f2f4a 2021-12-17 jrmu }
105 8f7f2f4a 2021-12-17 jrmu
106 8f7f2f4a 2021-12-17 jrmu }
107 8f7f2f4a 2021-12-17 jrmu
108 8f7f2f4a 2021-12-17 jrmu
109 8f7f2f4a 2021-12-17 jrmu one_time; # cats
110 8f7f2f4a 2021-12-17 jrmu
111 8f7f2f4a 2021-12-17 jrmu one_time; # dogs
112 8f7f2f4a 2021-12-17 jrmu
113 8f7f2f4a 2021-12-17 jrmu keys(%pets); # reset the hash iterator
114 8f7f2f4a 2021-12-17 jrmu
115 8f7f2f4a 2021-12-17 jrmu one_time; # cats
116 8f7f2f4a 2021-12-17 jrmu
117 8f7f2f4a 2021-12-17 jrmu one_time; # dogs
118 8f7f2f4a 2021-12-17 jrmu
119 8f7f2f4a 2021-12-17 jrmu one_time; # fish
120 8f7f2f4a 2021-12-17 jrmu
121 8f7f2f4a 2021-12-17 jrmu one_time; # end of hash
122 8f7f2f4a 2021-12-17 jrmu
123 8f7f2f4a 2021-12-17 jrmu one_time; # cats
124 8f7f2f4a 2021-12-17 jrmu
125 8f7f2f4a 2021-12-17 jrmu one_time; # dogs
126 8f7f2f4a 2021-12-17 jrmu
127 8f7f2f4a 2021-12-17 jrmu
128 8f7f2f4a 2021-12-17 jrmu > pet='cats', qty='2'
129 8f7f2f4a 2021-12-17 jrmu
130 8f7f2f4a 2021-12-17 jrmu > pet='dogs', qty='1'
131 8f7f2f4a 2021-12-17 jrmu
132 8f7f2f4a 2021-12-17 jrmu > pet='cats', qty='2'
133 8f7f2f4a 2021-12-17 jrmu
134 8f7f2f4a 2021-12-17 jrmu > pet='dogs', qty='1'
135 8f7f2f4a 2021-12-17 jrmu
136 8f7f2f4a 2021-12-17 jrmu > pet='fish', qty='3'
137 8f7f2f4a 2021-12-17 jrmu
138 8f7f2f4a 2021-12-17 jrmu > end of hash
139 8f7f2f4a 2021-12-17 jrmu
140 8f7f2f4a 2021-12-17 jrmu > pet='cats', qty='2'
141 8f7f2f4a 2021-12-17 jrmu
142 8f7f2f4a 2021-12-17 jrmu > pet='dogs', qty='1'
143 8f7f2f4a 2021-12-17 jrmu
144 8f7f2f4a 2021-12-17 jrmu
145 8f7f2f4a 2021-12-17 jrmu There is only one iterator variable connected with each hash, which
146 8f7f2f4a 2021-12-17 jrmu means calling each() on a hash in a loop that then calls each() on the
147 8f7f2f4a 2021-12-17 jrmu same hash another loop will cause problems. The example below goes
148 8f7f2f4a 2021-12-17 jrmu through the %pets hash and attempts to compare the quantity of different
149 8f7f2f4a 2021-12-17 jrmu pets and print out their comparison.
150 8f7f2f4a 2021-12-17 jrmu
151 8f7f2f4a 2021-12-17 jrmu
152 8f7f2f4a 2021-12-17 jrmu my %pets = (
153 8f7f2f4a 2021-12-17 jrmu
154 8f7f2f4a 2021-12-17 jrmu fish=>3,
155 8f7f2f4a 2021-12-17 jrmu
156 8f7f2f4a 2021-12-17 jrmu cats=>2,
157 8f7f2f4a 2021-12-17 jrmu
158 8f7f2f4a 2021-12-17 jrmu dogs=>1,
159 8f7f2f4a 2021-12-17 jrmu
160 8f7f2f4a 2021-12-17 jrmu );
161 8f7f2f4a 2021-12-17 jrmu
162 8f7f2f4a 2021-12-17 jrmu while(my($orig_pet,$orig_qty)=each(%pets)) {
163 8f7f2f4a 2021-12-17 jrmu
164 8f7f2f4a 2021-12-17 jrmu while(my($cmp_pet,$cmp_qty)=each(%pets)) {
165 8f7f2f4a 2021-12-17 jrmu
166 8f7f2f4a 2021-12-17 jrmu if($orig_qty>$cmp_qty) {
167 8f7f2f4a 2021-12-17 jrmu
168 8f7f2f4a 2021-12-17 jrmu print "there are more $orig_pet "
169 8f7f2f4a 2021-12-17 jrmu
170 8f7f2f4a 2021-12-17 jrmu ."than $cmp_pet\n";
171 8f7f2f4a 2021-12-17 jrmu
172 8f7f2f4a 2021-12-17 jrmu } else {
173 8f7f2f4a 2021-12-17 jrmu
174 8f7f2f4a 2021-12-17 jrmu print "there are less $orig_pet "
175 8f7f2f4a 2021-12-17 jrmu
176 8f7f2f4a 2021-12-17 jrmu ."than $cmp_pet\n";
177 8f7f2f4a 2021-12-17 jrmu
178 8f7f2f4a 2021-12-17 jrmu
179 8f7f2f4a 2021-12-17 jrmu }
180 8f7f2f4a 2021-12-17 jrmu
181 8f7f2f4a 2021-12-17 jrmu }
182 8f7f2f4a 2021-12-17 jrmu
183 8f7f2f4a 2021-12-17 jrmu }
184 8f7f2f4a 2021-12-17 jrmu
185 8f7f2f4a 2021-12-17 jrmu
186 8f7f2f4a 2021-12-17 jrmu > there are more cats than dogs
187 8f7f2f4a 2021-12-17 jrmu
188 8f7f2f4a 2021-12-17 jrmu > there are less cats than fish
189 8f7f2f4a 2021-12-17 jrmu
190 8f7f2f4a 2021-12-17 jrmu > there are more cats than dogs
191 8f7f2f4a 2021-12-17 jrmu
192 8f7f2f4a 2021-12-17 jrmu > there are less cats than fish
193 8f7f2f4a 2021-12-17 jrmu
194 8f7f2f4a 2021-12-17 jrmu > there are more cats than dogs
195 8f7f2f4a 2021-12-17 jrmu
196 8f7f2f4a 2021-12-17 jrmu > there are less cats than fish
197 8f7f2f4a 2021-12-17 jrmu
198 8f7f2f4a 2021-12-17 jrmu > there are more cats than dogs
199 8f7f2f4a 2021-12-17 jrmu
200 8f7f2f4a 2021-12-17 jrmu > there are less cats than fish
201 8f7f2f4a 2021-12-17 jrmu
202 8f7f2f4a 2021-12-17 jrmu > ...
203 8f7f2f4a 2021-12-17 jrmu
204 8f7f2f4a 2021-12-17 jrmu The outside loop calls each() and gets "cats". The inside loop calls
205 8f7f2f4a 2021-12-17 jrmu each() and gets "dogs". The inside loop continues, calls each() again,
206 8f7f2f4a 2021-12-17 jrmu and gets "fish". The inside loop calls each() one more time and gets an
207 8f7f2f4a 2021-12-17 jrmu empty list. The inside loop exits. The outside loop calls each() which
208 8f7f2f4a 2021-12-17 jrmu continues where the inside loop left off, namely at the end of the list,
209 8f7f2f4a 2021-12-17 jrmu and returns "cats". The code then enters the inside loop, and the
210 8f7f2f4a 2021-12-17 jrmu process repeats itself indefinitely.
211 8f7f2f4a 2021-12-17 jrmu
212 8f7f2f4a 2021-12-17 jrmu
213 8f7f2f4a 2021-12-17 jrmu One solution for this each() limitation is shown below. The inner loop
214 8f7f2f4a 2021-12-17 jrmu continues to call each() until it gets the key that matches the outer
215 8f7f2f4a 2021-12-17 jrmu loop key. The inner loop must skip the end of the hash (an undefined
216 8f7f2f4a 2021-12-17 jrmu key) and continue the inner loop. This also fixes a problem in the above
217 8f7f2f4a 2021-12-17 jrmu example in that we probably do not want to compare a key to itself.
218 8f7f2f4a 2021-12-17 jrmu
219 8f7f2f4a 2021-12-17 jrmu
220 8f7f2f4a 2021-12-17 jrmu my %pets = (
221 8f7f2f4a 2021-12-17 jrmu
222 8f7f2f4a 2021-12-17 jrmu fish=>3,
223 8f7f2f4a 2021-12-17 jrmu
224 8f7f2f4a 2021-12-17 jrmu cats=>2,
225 8f7f2f4a 2021-12-17 jrmu
226 8f7f2f4a 2021-12-17 jrmu dogs=>1,
227 8f7f2f4a 2021-12-17 jrmu
228 8f7f2f4a 2021-12-17 jrmu );
229 8f7f2f4a 2021-12-17 jrmu
230 8f7f2f4a 2021-12-17 jrmu
231 8f7f2f4a 2021-12-17 jrmu while(my($orig_pet,$orig_qty)=each(%pets)) {
232 8f7f2f4a 2021-12-17 jrmu
233 8f7f2f4a 2021-12-17 jrmu while(1) {
234 8f7f2f4a 2021-12-17 jrmu
235 8f7f2f4a 2021-12-17 jrmu my($cmp_pet,$cmp_qty)=each(%pets);
236 8f7f2f4a 2021-12-17 jrmu
237 8f7f2f4a 2021-12-17 jrmu next unless(defined($cmp_pet));
238 8f7f2f4a 2021-12-17 jrmu
239 8f7f2f4a 2021-12-17 jrmu last if($cmp_pet eq $orig_pet);
240 8f7f2f4a 2021-12-17 jrmu
241 8f7f2f4a 2021-12-17 jrmu if($orig_qty>$cmp_qty) {
242 8f7f2f4a 2021-12-17 jrmu
243 8f7f2f4a 2021-12-17 jrmu print "there are more $orig_pet "
244 8f7f2f4a 2021-12-17 jrmu
245 8f7f2f4a 2021-12-17 jrmu ."than $cmp_pet\n";
246 8f7f2f4a 2021-12-17 jrmu
247 8f7f2f4a 2021-12-17 jrmu } else {
248 8f7f2f4a 2021-12-17 jrmu
249 8f7f2f4a 2021-12-17 jrmu print "there are less $orig_pet "
250 8f7f2f4a 2021-12-17 jrmu
251 8f7f2f4a 2021-12-17 jrmu ."than $cmp_pet\n";
252 8f7f2f4a 2021-12-17 jrmu
253 8f7f2f4a 2021-12-17 jrmu }
254 8f7f2f4a 2021-12-17 jrmu
255 8f7f2f4a 2021-12-17 jrmu
256 8f7f2f4a 2021-12-17 jrmu }
257 8f7f2f4a 2021-12-17 jrmu
258 8f7f2f4a 2021-12-17 jrmu }
259 8f7f2f4a 2021-12-17 jrmu
260 8f7f2f4a 2021-12-17 jrmu
261 8f7f2f4a 2021-12-17 jrmu > there are more cats than dogs
262 8f7f2f4a 2021-12-17 jrmu
263 8f7f2f4a 2021-12-17 jrmu > there are less cats than fish
264 8f7f2f4a 2021-12-17 jrmu
265 8f7f2f4a 2021-12-17 jrmu > there are less dogs than fish
266 8f7f2f4a 2021-12-17 jrmu
267 8f7f2f4a 2021-12-17 jrmu > there are less dogs than cats
268 8f7f2f4a 2021-12-17 jrmu
269 8f7f2f4a 2021-12-17 jrmu > there are more fish than cats
270 8f7f2f4a 2021-12-17 jrmu
271 8f7f2f4a 2021-12-17 jrmu > there are more fish than dogs
272 8f7f2f4a 2021-12-17 jrmu
273 8f7f2f4a 2021-12-17 jrmu
274 8f7f2f4a 2021-12-17 jrmu If you do not know the outer loop key, either because its in someone
275 8f7f2f4a 2021-12-17 jrmu else's code and they do not pass it to you, or some similar problem,
276 8f7f2f4a 2021-12-17 jrmu then the only other solution is to call keys on the hash for all inner
277 8f7f2f4a 2021-12-17 jrmu loops, store the keys in an array, and loop through the array of keys
278 8f7f2f4a 2021-12-17 jrmu using foreach. The inner loop will then not rely on the internal hash
279 8f7f2f4a 2021-12-17 jrmu iterator value.
280 8f7f2f4a 2021-12-17 jrmu
281 8f7f2f4a 2021-12-17 jrmu
282 8f7f2f4a 2021-12-17 jrmu