coronalvrr has asked for the wisdom of the Perl Monks concerning the following question:

I need to compare the following arrays, compare them all
and output the comparisons to the screen:

my @D = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);<br> my @E = qq(a b c d e f g h i j k l m n o p q r s t u v w x y z);<br> my @F = (1, 3, 5, 7, 9);<br> my @G = qq(a b c d e f g h i j k l m);<br> my @H = (2, 4, 6, 8);<br> my @K = qq(n o p q r s t u v w x y z);<br> my @M = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);<br> my @P = qq(a b c d e f g h i j k l m n o p q r s t u v w x y z);<br> my @S = (1, 3, 5, 7, 9);<br> my @T = qq(a b c d e f g h i j k l m);<br> my @x = (2, 4, 6, 8);<br> my @Z = qq(n o p q r s t u v w x y z);<br>

I have so far:

use warnings;<br> use strict;<br> use diagnostics;<br> # use carp;<br> <br> sub check_same (\@\@);<br> <br> my @D = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);<br> my @E = qq(a b c d e f g h i j k l m n o p q r s t u v w x y z);<br> my @F = (1, 3, 5, 7, 9);<br> my @G = qq(a b c d e f g h i j k l m);<br> my @H = (2, 4, 6, 8);<br> my @K = qq(n o p q r s t u v w x y z);<br> my @M = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);<br> my @P = qq(a b c d e f g h i j k l m n o p q r s t u v w x y z);<br> my @S = (1, 3, 5, 7, 9);<br> my @T = qq(a b c d e f g h i j k l m);<br> my @x = (2, 4, 6, 8);<br> my @Z = qq(n o p q r s t u v w x y z);<br> print "\@D is not the same as \@E" if check_same (@D,@E,@F,@G,@H,@K,@M +,@P,@S,@T,@X,@Z);<br> print "\@D is the same as \@F" if check_same (@D,@E,@F,@G,@H,@K,@M,@P, +@S,@T,@X,@Z);<br> <br> <br> sub check_same (\@\@) {<br> my ($ref_one, $ref_two,) = @_;<br> # same size?<br> return 0 unless @$ref_one == @$ref_two;<br> for my $elem (0..$#$ref_one) {<br> return 0 unless $ref_one->[$elem] eq $ref_two->[$elem];<br> }<br> # same if we got this far<br> return 1;<br> }<br>

Replies are listed 'Best First'.
Re: compare and output to the screen
by ikegami (Patriarch) on Apr 25, 2009 at 15:34 UTC

    [ We'll both have an easier time if you use <c>...</c> around your code. ]

    The key to repeating the same action for multiple inputs is to store the inputs in a hash or array, not 12 variables.

    use strict; use warnings; sub compare_arrays { my ($array1, $array2) = @_; return 0 if @$array1 != @$array2; for my $i (0..$#$array1) { return 0 if $array1->[$i] ne $array2->[$i]; } return 1; } my %lists = ( D => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], E => [qq( a b c d e f g h i j k l m n o p q r s t u v w x y z )], F => [ 1, 3, 5, 7, 9 ], G => [qq( a b c d e f g h i j k l m )], H => [ 2, 4, 6, 8 ], K => [qq( n o p q r s t u v w x y z )], M => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], P => [qq( a b c d e f g h i j k l m n o p q r s t u v w x y z )], S => [ 1, 3, 5, 7, 9 ], T => [qq( a b c d e f g h i j k l m )], X => [ 2, 4, 6, 8 ], Z => [qq( n o p q r s t u v w x y z )], ); my @keys = keys %lists; for my $i1 (0..$#keys) { my $key1 = $keys[$i1]; for my $i2 ($i1+1..$#keys) { my $key2 = $keys[$i2]; if ( compare_arrays($lists{$key1}, $lists{$key2}) ) { print("$key1 is identical to $key2\n"); } else { #print("$key1 is different than $key2\n"); } } }
    S is identical to F T is identical to G X is identical to H P is identical to E K is identical to Z M is identical to D

    The reason for using

    my @keys = keys %lists; for my $i1 (0..$#keys) { my $key1 = $keys[$i1]; for my $i2 ($i1+1..$#keys) { my $key2 = $keys[$i2];

    instead of

    for my $key1 (keys %lists) { for my $key2 (keys %lists) {

    is to avoid useless duplication of outputs.

      I appreciate you help. I will take your advice and work on this.
Re: compare and output to the screen
by Corion (Patriarch) on Apr 25, 2009 at 15:22 UTC
      I'm beginning and unsure of where my problem is. I just figured I'd spend the day working on some code in an ongoing attempt to try to learn it. I thank you for your help and will check out FAQ 4
Re: compare and output to the screen
by graff (Chancellor) on Apr 25, 2009 at 15:41 UTC
    You can save yourself a lot of effort in posting by putting "<code>" at the beginning of your perl code, and "</code>" at the end.

    Your "check_same" sub is written to use just two array refs as args, but you are calling it with a long list of arrays (not refs to arrays). The two calls you have to check_same should look like this:

    print "\@D is not the same as \@E\n" unless check_same( \@D, \@E ); print "\@D is the same as \@F\n" if check_same( \@D, \@F );
    Apart from that, you should probably make your sub definition simpler (skip the "(\@\@)" part), but check to make sure the args are refs to arrays:
    sub check_same { my ( $ref1, $ref2 ) = @_; die "Bad args passed to check_array\n" unless ( ref( $ref1 ) eq 'ARRAY' and ref( $ref2 ) eq 'ARRAY' ) +; return 0 if @$ref1 != @$ref2; for my $i ( 0 .. $#$ref1 ) { return 0 if $$ref1[$i] ne $$ref2[$i]; } return 1; }
    You might also consider the "carp" or "croak" methods provided in Carp, instead of "die", to handle those kinds of error conditions in a subroutine.
      Thank you so much for your help. I will work on this and see how it goes