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

I'm stumped. Here's the code:
#!/usr/bin/perl -w use strict; my @configs; my $path = "/some-path"; my @clusterDirList = ("$path/cluster1", "$path/cluster2", "$path/clust +er3"); my %hash = ( 'remap.config' => 'remap.config.hosts:user|SApre-push.pl|NA', 'origin.db' => 'origin.db.hosts:user|SApre-push.pl|NA', 'local_cluster.db' => :user|SApre-push.pl|NA' ); my %HoL = ( 'cluster1' => [ 'remap.config', 'remap.config.hosts', 'origin.db', 'origin.db.hosts', 'local_cluster.db', 'local_cluster.hosts ] ); foreach my $key(keys %hash) { push @configs, $key; } foreach my $cluster (@clusterDirList) { foreach my $configfile (@configs) { push @{ $HoL{$cluster} } , $configfile; } }
What I'm struggling with is, I need to test for the existence of "$cluster.hosts" in %HoL{$cluster}

In other words, I need to determine whether or not, ie, "remap.config.hosts" is one of the multiple values stored in %HoL{$cluster}.
Can anyone shed some light on this?


Thanks,
Steve

Replies are listed 'Best First'.
Re: TestIs hash key a value contained in a hash of arrays?
by runrig (Abbot) on Aug 07, 2001 at 01:17 UTC
    Does that need to be an ordered list? If not, just use a hash of hashes and exists. Or iterate through the list:
    for (@{$HoA{cluster}}) { print "Matches\n" and last if $value eq $_; }
    Or some may suggest grep. I don't. The first() function from Scalar::Util would be better IMO:
    $found = first { $_ eq 'remap.config.hosts' } @{$HoA{cluster}};
Re: TestIs hash key a value contained in a hash of arrays?
by tachyon (Chancellor) on Aug 07, 2001 at 01:31 UTC

    Self explanatory I hope. We dereference our data structure as shown to get the array. We then use grep to search through the array for $find. the \Q....\E quotematas $find so the metachars get escaped. You could do it one one line of course my @matches = grep {/\Q$find\E/} @{$HoL{$cluster}};

    my %HoL = ( 'cluster1' => [ 'remap.config', 'remap.config.hosts', 'origin.db', 'origin.db.hosts', 'local_cluster.db', 'local_cluster.hosts' ] ); my $cluster = 'cluster1'; my @array = @{$HoL{$cluster}}; my $find = 'remap.config.hosts'; my @matches = grep { /\Q$find\E/ }@array; print "Found @matches" if @matches;

    Update

    You should use $_ eq $find in the grep unless you need a regex. If the array is big a for loop like runrig suggested will be much faster. If you just want true/false scalar grep will save a useless array. Hope this helps

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: TestIs hash key a value contained in a hash of arrays?
by Zaxo (Archbishop) on Aug 07, 2001 at 01:30 UTC
    sub is_present { my $cluster = shift; scalar grep {/^\Q$cluster\E\.hosts$/o} @{$HoL{$cluster}}; }

    TMTOWTDI is a vast understatement for functions like this

    Update: On reflection, I should be testing for equality, not match. I changed the re above to do that, but here is a better way:

    sub is_present { my $cluster = shift; scalar grep {$_ eq "$cluster.hosts"} @{$HoL{$cluster}}; }

    After Compline,
    Zaxo