Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Now, on a broader note.

Your %dependencies hash is a list, by key, of the keys that key depends on. This is inconvenient for what you're trying to do, which is why you're jumping through some hoops.

To put the function in english:

foreach key foreach dependency of that key if this dependency is the one I want to delete, delete this key continue looping continue looping

Now, note that in the middle, if you decide to delete this key, you're still continuing to loop over its dependencies. So you'd really want to break out of there.

But better, you can avoid that loop completely, and just ask the question "am I ($key) one of the elements in this array?" with grep:

if( grep { $_ eq $key } @{$dependencies{$key}} ) { print "Going to call sub for $key\n"; mydel($key); }

That saves you writing the loop.

But, let's step back. The key you're deleting probably isn't a dependency for most of the keys in the hash. If you're going to be calling this a lot, it can be a little annoying spending all that time searching over lists you're not in. You're having to do that because your list shows the dependencies of each key.

But it would be even more convenient if instead it showed the keys that depend on each key. Then you could just loop over that list, deleting stuff. And it's pretty each to build that list from the one you have. Something like:

my %requiredby; for my $key (keys $dependencies) { for my $dep (@{$dependencies{$key}}) { push @{$requiredby{$dep}}, $key; } } # Or alternately, using a statement modifier to be shorter my %requiredby; for my $key (keys %dependencies) { push @{$requiredby{$_}}, $key for @{$dependencies{$key}}; }

Now you've got a lookup you can just loop directly over, and you can get even shorter. Obviously it costs some time and memory to build that %requiredby list, but if you're going to call the delete often, it's worth it. New version (tested):

#!/usr/bin/env perl5 use strict; use warnings; my %hash = ( 'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'five' + => 5); my %dependencies = ( 'one' => [], 'two' => [], 'three' => ['four'], 'four' => ['one','two'], 'five' => ['three'] ); my %requiredby; for my $key (keys %dependencies) { push @{$requiredby{$_}}, $key for @{$dependencies{$key}}; } sub my_del { my $thiskey = shift; # Find all the keys that depend on us, and so have to go for my $del ( @{$requiredby{$thiskey}} ) { # Recurse and delete one key that requires us print "Going to call sub for $del\n"; my_del($del); } # And finally get rid of us delete $hash{$thiskey}; print "Deleting $thiskey\n"; } my_del('one');
% ./tst.pl Going to call sub for four Going to call sub for three Going to call sub for five Deleting five Deleting three Deleting four Deleting one

Of course, won't catch infinite loops, like if we set four to depend on three as well. That's left as an exercise for the reader :)


In reply to Re: Scoping problems with recursive function by fullermd
in thread Scoping problems with recursive function by morrin

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-16 23:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found