This entry will primarily go over various approaches towards iterating over structures of data. This will include basic looping as well as equivalents to Perl’s map
& grep
.
This is not intended to be an exhaustive guide or a best practice for either language. The attempt, as with all articles in this series, is to provide a basic set of mappings between the languages.
Iterating over collections
To loop over all the items in an array in Perl you would probably use the for
loop construct:
for my $item (@array) {…}
You could do something similar in Groovy using the each
method on collections:
list.each {…}
To loop over all the keys in a hash (or Map) you can combine the above with the keys
builtin:
for my $key (keys(%hash)) {…}
In Groovy you simply use a lambda that accepts two parameters.
myMap.each { key, _value -> … }
Looping over all the values is similar to the examples above in both, so I will skip that. Looping over each entry in the hash with both the key and value in Groovy is the same as the example above, in Perl you would have to use each
, which I don’t like.
It is important to note that with Groovy’s each
different things are passed in based on the number of parameters. The example above gave each
a 2 parameter lambda and so the lambda got inputs of [key, value]. Had a 1 parameter lambda been passed in then that lambda would have received an Entry object that had accessors for the key and value.
Iterating over a Set of Integers
Both Perl and Groovy provide many ways to iterate over a range. One popular approach in Perl is to use the dot-dot range operator (..) and for
looping construct. By using this it is simple to print all the numbers between one and ten:
for my $num (1..10) { print $num }
Groovy has a similar approach:
(1..10).each { print it }
Groovy has a couple other ways to do the same thing, for example numbers have an upto
method attached to them that can be used to iterate. As such, the same thing above could be written as:
1.upto(10) { print it }
Of course, Perl also has the ability to loop via the while
looping construct and Groovy could loop using a for in
on top of what I’ve listed here.
If you wanted to iterate over a set of integers that didn’t increment by one in Perl you might use map
and for
like this:
for my $multiple_of_five ( map { $_ * 5 } 1..5) {…}
Or you might use grep
and for
like this:
for my $multiple_of_five ( grep { not $_ % 5 } 1..25) {…}
Or, of course, you could pick up a useful module, like Math::Sequence.
In Groovy you would simply do this:
5.step(25,5) {…}
Mapping a List
Perl helpfully provides the map
builtin to easily map a list of values from one to another. For example, were a developer wanting to square all the values in a list they would:
my @squared = map { $_**2 } @original_values
The same thing can be performed in Groovy using the collect() method on collections:
List squared = originalValues.collect { it.power(2) }
Grepping a List
Perl provides the grep
builtin to easily filter values out of a list and provide a new list with only the remaining values. For example, if a developer was looking for all the items in a list that were odd they could:
my @odd = grep { $_ % 2 } @numbers
To do this in Groovy they would use the findAll
method that exists on collections:
List odd = numbers.findAll { it % 2 }
Grepping for the First Item in a List
Perl has a number of modules which are considered ‘core’. It is reasonable to assume any core module is installed and readily available. To get the first item in a list that matches some criteria a Perl developer could use the example above for grepping a list and shift
off the top, but more likely they would use List::Util’s first
like this:
my $first_odd = first { $_ % 2} @numbers
A similar approach in Groovy could be done via the find
method on collections:
def firstOdd = numbers.find { it % 2 }