How do I test whether two arrays or hashes are equal?

The following code works for single-level arrays. It uses a stringwise comparison, and does not distinguish defined versus undefined empty strings. Modify if you have other needs.

    $are_equal = compare_arrays(\@frogs, \@toads);
    sub compare_arrays {
	my ($first, $second) = @_;
	no warnings;  # silence spurious -w undef complaints
	return 0 unless @$first == @$second;
	for (my $i = 0; $i < @$first; $i++) {
	    return 0 if $first->[$i] ne $second->[$i];
	}
	return 1;
    }
For multilevel structures, you may wish to use an approach more like this one. It uses the CPAN module FreezeThaw:

    use FreezeThaw qw(cmpStr);
    @a = @b = ( "this", "that", [ "more", "stuff" ] );
    printf "a and b contain %s arrays\n",
        cmpStr(\@a, \@b) == 0 
	    ? "the same" 
	    : "different";
This approach also works for comparing hashes. Here we'll demonstrate two different answers:

    use FreezeThaw qw(cmpStr cmpStrHard);
    %a = %b = ( "this" => "that", "extra" => [ "more", "stuff" ] );
    $a{EXTRA} = \%b;
    $b{EXTRA} = \%a;                    
    printf "a and b contain %s hashes\n",
	cmpStr(\%a, \%b) == 0 ? "the same" : "different";
    printf "a and b contain %s hashes\n",
	cmpStrHard(\%a, \%b) == 0 ? "the same" : "different";
The first reports that both those the hashes contain the same data, while the second reports that they do not. Which you prefer is left as an exercise to the reader.
Back to perlfaq4