in reply to While loop and LAST

To avoid the each iterator issue that BrowserUk mentioned, use keys in a for loop instead (replacing the first six lines of your while loop with these):

for $key ( keys %job_categories ) { print ( "looking in $job_title for\: $key \n"); if ($job_title =~ /$key/i) { $department = $job_categories{$key}; print ( "found a match. setting department to $job_catego +ries{$key} \n");

Hope this helps!

Replies are listed 'Best First'.
Re^2: While loop and LAST
by BrowserUk (Patriarch) on Nov 02, 2013 at 07:07 UTC

    Hm. If the hash is of any size, that is a much slower and more memory hungry approach to solving the problem than simply using keys %job_categories; within the outer loop to reset the iterator:

    $h{ $_ } = $_ for 0 .. 1e6;; cmpthese 1,{ a=>q[ while( ( $k, $v ) = each %h ){ my $x = "$k:$v"; } ], b=>q[ for my $k ( keys %h ){ my $x = "$k:$h{$k}"; } ], };; s/iter b a b 8.67 -- -83% a 1.52 472% --

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      The OP's hash contained only two sample keys. Given the task, I'd be surprised if keys > 500, but my guess isn't too meaningful.

      Thank you both for the help. I am thinking this is unlikely to become a large hash (looks like BroswerUK simulated a million key pairs). I don't quite understand while there is a big difference in memory and performance. I'm always looking for elegance and performance so I plan to play with BrowserUK's idea; of course code that I understand is pretty important also.
        I don't quite understand while there is a big difference in memory and performance.

        The for loop creates a list of the keys which is allocated on the (perl) stack.

        Effectively, it has to perform the equivalent of your while loop (discarding the values) to generate that list and needs to allocate memory to construct the list

        It then iterates that list and has to do a second lookup of each key to obtain the value.

        And each time you short-circuit the loop with next, large chunks of the work done to build the list will be discarded and it all needs to be re-done for the next iteration of the outer loop.

        Conversely, the while loop retrieves both key and value together with no secondary lookup and no need to allocate memory. Resetting the iterator with keys %hash; in a void context is a simple, single assignment. And when you short-circuit the loop; you not only don't discard substantial effort already expended; you avoid expending the effort that would be discarded. That's a double saving.

        Even if your hash is of relatively modest size; those savings will be multiplied by the iteration count of the outer loop and will make a considerable difference.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.