Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Recursively traverse two data structures and test for match

by TedPride (Priest)
on May 22, 2005 at 23:12 UTC ( #459398=snippet: print w/ replies, xml ) Need Help??

Description: Recursively traverses two data structures and tests for match. Takes any data type; arrays and hashes must be passed by reference. Returns false if two arrays have the same items in a different order. Streamlined for speed with large numbers of data items.

EDIT: Edited to test CODE refs.

use strict;
use warnings;

sub match {
    return ($_[0] eq $_[1] ? 1 : 0) if ! ref $_[0] && ! ref $_[1];
    my ($x, $y, $i) = @_;
    return 0 if ref $x ne ref $y;
    if (ref $x eq 'ARRAY') {
        return 0 if $#$x != $#$y;
        for ($i = 0; $i <= $#$x; $i++) {
            return 0 if ! match($x->[$i], $y->[$i]);
        } return 1;
    }
    if (ref $x eq 'HASH') {
        return 0 if scalar keys %$x != scalar keys %$y;
        my @x = sort keys %$x;
        my @y = sort keys %$y;
        for ($i = 0; $i <= $#x; $i++) {
            return 0 if $x[$i] ne $y[$i];
        }
        for ($i = 0; $i <= $#x; $i++) {
            return 0 if ! match($x->{$x[$i]}, $y->{$y[$i]});
        } return 1;
    }
    return ($x eq $y ? 1 : 0);
}
Comment on Recursively traverse two data structures and test for match
Download Code
Re: Recursively traverse two data structures and test for match
by dragonchild (Archbishop) on May 23, 2005 at 01:09 UTC
    What does this provide over Test::More's is_deeply()?

    • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
    • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"
Re: Recursively traverse two data structures and test for match
by diotalevi (Canon) on May 23, 2005 at 01:32 UTC
    Neither this nor Test::More's is_deeply correctly handle overloaded values.
      That's not a slam on anything that uses overloaded values. There's just a problem with how overloading is done. I wrote about it here. There's just no correct way to compare overloaded values from different classes.

      • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
      • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"
        You didn't understand. If you wished to compare that two structures were identical as if overloading didn't exist, you're out of luck. Test::More's is_deeply doesn't do anything to disable the overloading and to thus act on the data structure transparently.
Re: Recursively traverse two data structures and test for match
by TedPride (Priest) on May 23, 2005 at 17:39 UTC
    I imagine the routine doesn't provide anything over Test::More, but I thought it would be fun to roll one on my own. Besides, you can just cut and paste this routine into your program - no need to mess with installing modules.

    I notice I didn't include tests for CODE refs, however. I'm a naughty boy.

      I didn't see you testing for cycles. Any self referential structure is going to cause your code to stop in an infinite loop.

Back to Snippets Section

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://459398]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2014-07-31 02:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (244 votes), past polls