in reply to Re: Compare array of hashes
in thread Compare array of hashes

foreach my $arrayItem1(@{$$HOAOH1{details}}) { foreach my $arrayItem2(@{$$HOAOH2{details}}) { foreach my $keyArrayItem1(sort keys%$arrayItem1) { if ($$arrayItem1{$keyArrayItem1} eq $$arrayItem2{$keyArray +Item1}) { print "Match:$$arrayItem1{$keyArrayItem1} $$arrayItem2 +{$keyArrayItem1}\n"; } } } }
I tried this but it compares each key of every Hash in structure1 with each key of every Hash in structure2.

Replies are listed 'Best First'.
Re^3: Compare array of hashes
by pryrt (Abbot) on Aug 26, 2016 at 15:41 UTC

    ++AnishaM: Good progress. From reading your original question, the results you show are what I thought you wanted. Given that you don't seem happy with those results, here are further ideas

    but it compares each key of every Hash in structure1 with each key of every Hash in structure2

    friendly pedant mode: Technically, for every row (subhash) of the first array and for every row (subhash) of the second array, you are comparing the value of each key in the first subhash to the value of the same key of the second subhash, for a total of 5*5*3=75 comparisons. If you were really comparing the value of every key of each subhash (ie, comparing name to 'name', 'time', and 'place', etc), it would be 5*5*3*3=225 comparisons.

    If you really only want to compare the first row of HOAOH1 with the first row of HOAOH2, the second row with the second row, etc (for a total of 5 outer comparisons and 3 key comparisons = 25), here's a hint: since you want the row# to match for each subhash that's compared, you might want to collapse the arrayItem1 and arrayItem2 loops into a single loop that gives an index, and then use that index to find the appropriate row from each HOAOH#

    I would also recommend printing something during the FALSE condition of your compare, as well, so that you can see better what's going on and how many loops are being executed. You might want to add the outer loop variables to your print statements (whether they be references, indexes, or what have you), so that way you can tell exactly which pairs are being compared.


    update 1: reword the pedant-mode to be more pedantically correct (100% correctness not guaranteed). :-)

    update 2: fix brackets to parenthesis in update 1

Re^3: Compare array of hashes
by Marshall (Canon) on Aug 27, 2016 at 21:36 UTC
    Congratulations AnishaM++. You current code represents a huge leap forward in understanding!

    A few nits, @{$$HOAOH1{details}}... Usually the de-referencing operator "->" would be preferred over the double "$$". This code means exactly the same thing and many would find this easier to read:

    foreach my $arrayItem1(@{$HOAOH1->{details}}) { foreach my $arrayItem2(@{$HOAOH2->{details}}) { foreach my $keyArrayItem1(sort keys %$arrayItem1) { if ($arrayItem1->{$keyArrayItem1} eq $arrayItem2->{$keyArr +ayItem1}) { print "Match:$arrayItem1->{$keyArrayItem1} $arrayItem2 +->{$keyArrayItem1}\n"; } } } } __END__ Match:AB AB Match:1234 1234 Match:CD CD Match:5678 5678 Match:EF EF Match:91011 91011 Match:GH GH Match:121314 121314 Match:cccc cccc Match:IJ IJ Match:151617 151617
    I also had to add quotes around 'AB", 'IJ', etc. in order to make "strict" happy. An assignment that doesn't compile under strict is unusual. use strict; use warnings; will save you a lot of grief in the future. I highly recommend that.

    The code contains a mixture of tabs and spaces. I think as you write more code, you will find that spaces only are the way to go. My tab isn't the same as your tab, etc. Editors designed for writing programs will have a setting "convert tabs to spaces". That makes everything clear and the extra bytes for the spaces vs a tab is meaningless.

    Looking at the output, it is hard for me to figure out what records are involved when something matches/doesn't match. pryrt has some suggestions in that regard. I'd re-read the text of the assignment closely to see if there is some clue about what the instructor wants in terms of output format.