in reply to Compare complex perl data structures

Hi,

Since your arrays are not in order you may like to look at Test::Deep -- in particular its bag routines.

Update:

Here's a solution that works even if you do not know in advance what the elements of your arrays are going to contain. Before placing all the elements of your arrayref into a bag, it recursively goes through the elements and passes each to a subroutine that places any nested arrayrefs into their own sub-bag:

( Disclaimer: there may be a more elegant way to do this using some of Test::Deep's, er, deeper methods ... )

use strict; use warnings; use Test::More; use Test::Deep; use utf8; my ( $v, $w, $x, $y ) = get_data(); my @wanted = map { bagify($_) } @{ $v }; cmp_deeply( $w, bag( @wanted ), 'OP data' ); my @deeper = map { bagify($_) } @{ $x }; cmp_deeply( $y, bag( @deeper ), 'deeper nesting' ); done_testing; sub bagify { my $input = shift; my $output; if ( ref $input eq 'HASH' ) { while ( my ( $key, $val ) = each %{ $input } ) { $output->{ $key } = bagify($val); } } elsif ( ref $input eq 'ARRAY' ) { $output = bag( map { bagify($_) } @{ $input } ); } else { $output = $input; } return $output; } sub get_data { my @v = ( {'platformid' => '100','da' => 'A.9','os' => 'microsoft amd64 wNT- +6.1-S','ma' => 'A.9','cc' => 'A.9','size' => [{'objecttype' => 'OB2BA +R','totalsize' => '230986 KB','application' => 'IDB','hostname' => '5 +096'},{'objecttype' => 'WINFS','totalsize' => '1262152 KB','applicati +on' => 'R: [New Volume]','hostname' => '5096'},{'objecttype' => 'WINF +S','totalsize' => '574463 KB','application' => 'C:','hostname' => '50 +96'}],'objecttype' => '6','host' => '5096'}, {'platformid' => '22','d +a' => 'A.9','os' => 'hp-ux-11.31','host' => '2060','cc' => 'A.9','ma' + => 'A.9','size' => [{'objecttype' => 'FILESYSTEM','totalsize' => '36 +28129 KB','application' => '/depot','hostname' => '2060'}],'objecttyp +e' => '2'} ); my @w = ( {'platformid' => '22','da' => 'A.9','os' => 'hp-ux-11.31','host' = +> '2060','cc' => 'A.9','ma' => 'A.9','size' => [{'objecttype' => 'FIL +ESYSTEM','totalsize' => '3628129 KB','application' => '/depot','hostn +ame' => '2060'}],'objecttype' => '2'}, {'platformid' => '100','da' => + 'A.9','os' => 'microsoft amd64 wNT-6.1-S','ma' => 'A.9','cc' => 'A.9 +','size' => [{'objecttype' => 'OB2BAR','totalsize' => '230986 KB','ap +plication' => 'IDB','hostname' => '5096'},{'objecttype' => 'WINFS','t +otalsize' => '1262152 KB','application' => 'R: [New Volume]','hostnam +e' => '5096'},{'objecttype' => 'WINFS','totalsize' => '574463 KB','ap +plication' => 'C:','hostname' => '5096'}],'objecttype' => '6','host' +=> '5096'} ); my @x = ( { a => { uc => 'A', accented => [qw/á à/] }, b => 'B', c => [ +{ foo => 'bar' }, { baz => [qw/q u x/, { nested => [qw/even more/] }] + } ] }, { d => ['D', [qw/nested array/] ], e => 'E', f => [ { xyz => ' +abc' }, { zzz => 'ZZZ' } ] }, ); my @y = ( { e => 'E', f => [ { zzz => 'ZZZ' }, { xyz => 'abc' } ], d => +[ [qw/array nested/], 'D'] }, { a => { uc => 'A', accented => [qw/à á/] }, c => [ { baz => [ + { nested => [qw/more even/] }, qw/x u q/] }, { foo => 'bar' } ], b = +> 'B' }, ); return ( \@v, \@w, \@x, \@y ); }
Output:
perl 1174098-2.pl ok 1 - OP data ok 2 - deeper nesting 1..2

Update: updated code to remove redundant ref() checks.

Original reply:

use strict; use warnings; use Test::More; use Test::Deep; my @x = ( { a => 'A', b => 'B', c => [ { foo => 'bar' }, { baz => 'qux' } ] +}, { d => 'D', e => 'E', f => [ { xyz => 'abc' }, { zzz => 'ZZZ' } ] +}, ); my @y = ( { d => 'D', e => 'E', f => [ { xyz => 'abc' }, { zzz => 'ZZZ' } ] +}, { a => 'A', b => 'B', c => [ { foo => 'bar' }, { baz => 'qux' } ] +}, ); cmp_deeply( \@x, bag(@y) ); done_testing;
Output:
$ perl 1174098.pl ok 1 1..1

If the hash key values are themselves possibly unordered arrays you'll have to figure out from the module documentation what to do about that.

Hope this helps :-)

The way forward always starts with a minimal test.