Is it possible to evaluate a changing hash (changed within a loop)?

Z

zhilianghu

Let me fake an example for the problem -- Let's say I have a need to
traverse through a pedigree to find certain (qualified) ancestor for a
number of children, and count how many children a qualified ancestor
has. This process requires evaluation of the outcome at each
generation to be or not to be a qualified ancestor, or search will go
on.

I'd like to design a hash to hold the current element children:

%examiner = (
'John', '1',
'Scot', '1',
... ...
);

I'd then loop the hash to search a database for the parents of each
child, see if it's a qualified ancestor: if yes, stop on this one; if
not, increment the number of children, and continue the search (next
would be evaluating the grant-parents, grant-grant-parents, and so
on).... until all children in the starting elements are traced to a
qualified ancestor.

while (($name, $count) = each %examiner ) {
# - find parent of $name
# - see of the parent qualify
# - if yes, update the %examiner to turn the "count" to "0";
# - if not, add new parent(s) to %examiner for next round
evaluation
# - if all elements in the hash are "0", finish.
}

My question is, can a hash be updated while being evaluated? In other
words, can a hash be "re-evaluated" until its changing value satisfy
certain criteria?
So far, my experimenting shows it only evaluates each element once,
then quit, regardless how the hash content is changed. Is another loop
structure needed in order to loop for the 2nd, 3rd,... rounds
evaluation (on the updated hash)? Or there is a simpler way...?

Any advice is appreciated!

Zhiliang
 
X

xhoster

while (($name, $count) = each %examiner ) {

Showing code is good. Thank you. Unfortunatley, you didn't show enough
of it.
# - find parent of $name

Say it in perl.
my $parent = find_parent($name);
# - see of the parent qualify

if (is_qualifying($parent)) {
# - if yes, update the %examiner to turn the "count" to "0";

$examiner{$name}=0; # is this what you meant?
# - if not, add new parent(s) to %examiner for next round evaluation

} else {
$examiner{$parent}=1; # Is this what you mean?
}
# - if all elements in the hash are "0", finish.
last unless grep $_>0 , values %examiner.

Ignoring your actual question for minute, I don't see how this code
(assuming my guesses were right) will ever finish. If a name does
not have a direct parent which qualifies, then its parent will get added to
the hash, but the child itself will never get set to zero. Also, once a
entry is set to zero, it never has to be looked up again, right?
My question is, can a hash be updated while being evaluated? In other
words, can a hash be "re-evaluated" until its changing value satisfy
certain criteria?

perldoc -f each

If you add or delete elements of a hash while you're
iterating over it, you may get entries skipped or
duplicated, so don't.

So far, my experimenting shows it only evaluates each element once,
then quit, regardless how the hash content is changed. Is another loop
structure needed in order to loop for the 2nd, 3rd,... rounds
evaluation (on the updated hash)? Or there is a simpler way...?

There are many ways. Here is one (of course, it may be an infinite
loop, as discussed above. I can't solve that part, as I don't know what
you really want.

while (my @x = grep $examiner{$_}>0 , keys %examiner) {
foreach my $name (@x) {
my $parent = find_parent($name);
if (is_qualifying($parent)) {
$examiner{$name}=0;
} else {
$examiner{$parent}=1 unless exists $examiner{$parent};
}
};
};


This is kind of like breadth first search. I would probably actually
do it as a depth first search, but that doesn't seem to fit in with
sample code you provided. I'm not entirely sure how this solves your
prose problem description, as you only describe count as getting
decremented, never incremented, so I don't know how anything is supposed to
actually get counted.

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,142
Latest member
arinsharma
Top