http://qs1969.pair.com?node_id=1081167

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

Essentially, I have a process that puts parties in particular transactional roles and am trying to compare production values to uat values. The data is being improved and re-mapped, and I'm trying to figure out how to quantify this.

At this point, I have a loop over the hashes that will compare values, so it will compare a production transaction for a particular role to the uat transaction for the same role and print it (so I can determine if it's changed, added, or removed). In some cases, however, a party has been remapped to a different role. I'd like to reflect this, so if I find the role defined with a value in production I really want to cycle through all the roles defined for the UAT transaction and check if I see the same value, and then print the value it's moved to.

I'm only trying to do this if the role is undefined in UAT, and honestly I'm not sure this is actually what I will eventually need. Essentially I was asked for "how much data has been changed?" -- for several hundred thousand records, for several fields, in moderately complex transactions. What I have does go partway towards that, but I still think it could be improved.

Anyway, comments appreciated.
print "Transaction ID\tPROD\tUAT Tran ID\tUAT\n"; # $key = transaction ID # $value = detail data of interest #prod hash is just a hash on transaction id (the reference is to a spe +cific role). UAT hash is a HoH of ## $uat{transaction id}{role} while (my ($key, $value) = each(%$prod)) { print "$key\t$value\t"; exists $uat_tid{$key}?print "$uat_tid{$key}\t":print "No UAT trans + id\t"; exists $uat->{$key}{$inrole}?print "$uat->{$key}{$inrole}":for my +$role_key ( keys %{$uat->{$key} } ) { print $role_key if $uat->{$key}{$role_key} eq $value}; ## iterate through UAT hash for transaction id to determine if par +ty has been remapped to a different role # Does the code below work? And if so, can I really insert it th +e way I did into the trinary operator above? # for my $role_key ( keys %{$uat->{$key} } ) # { print $role_key if $uat->{$key}{$role_key} eq $value;} print "\n"; }




-----------------
s''limp';@p=split '!','n!h!p!';s,m,s,;$s=y;$c=slice @p1;so brutally;d;$n=reverse;$c=$s**$#p;print(''.$c^chop($n))while($c/=$#p)>=1;

Replies are listed 'Best First'.
Re: Iterating over second key in HoH defined by reference
by Laurent_R (Canon) on Apr 04, 2014 at 18:03 UTC
    I don't really understand your context, but if you want to iterate through nested hashes, it is usually easier to use the values function, rather than the keys function. Just a short example on how easy it is:
    use strict; use warnings; my %hash = ( A => { F => 1, G => "3A", H => 5 }, B => { F => 1, G => "3B", H => 5 }, C => { F => 1, G => "3C", H => 5 }, D => { F => 1, G => "3D", H => 5 }, E => { F => 1, G => "3E", H => 5 }, ); print "$_->{G} " for (values %hash);
    which prints:
    3A 3D 3C 3E 3B
    Or, if you want to go through the values of the inner hashes:
    print join " ", map {values %{$_}, "-"} values %hash;
    Output:
    5 1 3A - 5 1 3D - 5 1 3C - 5 1 3E - 5 1 3B -
Re: Iterating over second key in HoH defined by reference
by kcott (Archbishop) on Apr 05, 2014 at 00:16 UTC

    G'day SamCG,

    A small, representative example of data, together with a short, self-contained script that reproduces what you're attempting to achieve, would go a long way to getting a better answer. If terms such as "parties", "transactional roles", "production values", and so on, are important in understanding your problem domain, please provide appropriate descriptions.

    "... but I still think it could be improved"

    Here's some suggestions for improvement (particularly with respect to readability and maintainability).

    Using statements, as opposed to simple values, for the ternary operators's 2nd and 3rd operands, leads to all sorts of problems (often related to precedence), reduces readability, and increases the difficulty of maintenance: all of this leads to error-prone code. See the documentation (link provided) for examples.

    This

    exists $uat_tid{$key}?print "$uat_tid{$key}\t":print "No UAT trans id\ +t";

    would probably be better as

    print exists $uat_tid{$key} ? $uat_tid{$key} : 'No UAT trans id', "\t" +;

    And this

    exists $uat->{$key}{$inrole}?print "$uat->{$key}{$inrole}":for my $rol +e_key ( keys %{$uat->{$key} } ) { print $role_key if $uat->{$key}{$role_key} eq $value};

    would definitely be better as

    if (exists $uat->{$key}{$inrole}) { print $uat->{$key}{$inrole}; } else { for my $role_key (keys %{$uat->{$key}}) { print $role_key if $uat->{$key}{$role_key} eq $value; } }
    "Does the code below work?"

    I don't really know what you're asking. Short answer: run it and find out for yourself. Longer answer: explain what it's supposed to do and why the "Short answer" is inadequate.

    "And if so, can I really insert it the way I did into the trinary operator above?"

    As already explained, even attempting to do so is not a good idea.

    -- Ken

Re: Iterating over second key in HoH defined by reference
by GotToBTru (Prior) on Apr 04, 2014 at 16:52 UTC

    Could really use some sample data here.