G. Cito
G. Cito

Reputation: 6378

Simple elementwise comparison of arrays using operators

To compare each element of arrays that I know are the same length (and which have a predictable order) in perl we have each_arrayref which can be added to useful subroutines or just used directly:

use List::AllUtils qw/each_arrayref/;

my ($arr1, $arr2) = ( [10, 31, 12], [20, 21, 14] );

my $iterate_elems = each_arrayref($arr1, $arr2); 
while ( my ($x, $y) = $iterate_elems->() ) { 
   say $x lt $y ? "$x is lower " : "$x is higher" ; 
}

or one-lineishly for cut and paste:

perl -MList::AllUtils=each_arrayref -E '
  my $iter = each_arrayref([10, 31, 12], [20, 21, 14]); 
  while ( my ($x, $y) = $iter->() ){ 
  say $x lt $y ? "$x lower" : "$x higher"}'

But this seems a tad awkward and not completely foolproof. I try to use a descriptive term like $iterate_elems as the iterating function reference to help. Perhaps I don't use this enough for it to seem obvious.

In perl6 there are metaoperators which allow for all kinds of fairly succinct and cool list comparisons and munging. This leads me to think there must be a way one could use operator overloading in perl5 to do this. Can anyone comment on the wisdom of this? It seems like it might be easier to understand code written in a way that applies operators to a series of lists instead of iterating through the lists to apply operators. Perhaps creative use of map or List::MoreUtils's apply would achieve the same thing.

Astonishing perl6 code samples especially welcome.

Upvotes: 2

Views: 288

Answers (1)

Coleoid
Coleoid

Reputation: 95

Since you're using List::AllUtils, how about pairwise?

use List::AllUtils qw(pairwise);

my @arr1 = (10, 31, 12);
my @arr2 = (20, 21, 14);

pairwise { 
    print $a lt $b ? "$a is lower\n" : "$a is higher\n"
} @arr1, @arr2;

That fits your problem as stated, and seems simpler to me, but 'simple' is slippery... Best of luck!

Upvotes: 1

Related Questions