in reply to Ludicrously Stupid Foreach Loop Question

G'day chaoticset,

I'm assuming that we have lists that look like this:

@oldstock = ("widgets:10:5", "wodgets:4:2", "spanners:5:3"); @newstock = ("screwdrivers:8:3", "hammers:5:1", "widgets:3:1");
And we want to end up with a list like this:
@totalstock = ("widgets:13:6", # Both widget entries joined "wodgets:4:2", "spanners:5:3", "screwdrivers:8:3", "hammers:5:1");
I'm also assuming that the lists are un-ordered, and the ordering of the final list does not matter.

This is a perfect opportunity to use hashes. We have an obvious key (the name), and values (stock and shown). Given that all we really want to do is join the lists together, we should just be able to iterate through them, use some hashes to build our results, and them print them. Here's an example using the arrays above:

my %stock = (); my %shown = (); # Build our records foreach my $record (@newstock @oldstock) { my ($name, $stock, $shown) = split(/:/$record); $stock{$name} += $stock; $shown{$name} += $shown; } # Print the result. foreach my $name (keys %stock) { print join(":",$name,$stock{name},$shown{name}),"\n"; }
You could do the same thing using a single hash and references, but I believe the above is more simple to understand.

Hope that the above helps.

Cheers,
Paul

Update: Updated to not check for the existance of entries in the hashes, but just += them anyway. I was doing an explicit test with exists() in order to avoid warnings, but as it happens using += with an undefined lvalue doesn't produce a warning anyway. Thanks to cLive ;-) for pointing this out.

Replies are listed 'Best First'.
Re: Ludicrously Stupid Foreach Loop Question
by cLive ;-) (Prior) on Oct 09, 2001 at 09:28 UTC
    ah, oops, my point exactly (blush). Small point:
    if (exists($stock{$name})) { $stock{$name} += $stock; $shown{$name} += $shown; } else { $stock{$name} = $stock; $shown{$name} = $shown; }
    You don't need to check it exists:
    $stock{$name} += ($stock + $shown);
    will do.

    cLive ;-)

      G'day cLive,

      The code that you've given above is slightly different from what I used in my example. I was keeping stock and shown seperated, whereas your code is adding them together. I was uncertain which the original poster required, so I erred on the side of caution and went with the most flexible result.

      My original post mentions that checking for the existance of hash entries is intentional, in order to avoid warnings. However after checking with perl 5.6.1 and 5.005_03, += does not produce a warning if used with an undefined lvalue, so you're right, it is un-necessary even for avoiding warnings.

      Thanks for the feedback, I'll update my original post accordingly.

      Cheers,
      Paul