web-dev-qa-db-ja.com

値による単純なハッシュ検索

単純なハッシュがあり、$ value基準に基づいて$ keyを返したいのですが。つまり、14行目で、$ valueが「黄色」である$ keyを返すために必要なコードは何ですか。

1  #!/usr/bin/Perl
2
3  # This program creates a hash then
4  # prints out what is in the hash
5
6  %fruit = (
7   'Apple' => ['red','green'],
8   'kiwi' => 'green',
9   'banana' => 'yellow',
10  );
11
12 print "The Apple is @{$fruit{Apple}}.\n";
13 print "The kiwi is $fruit{kiwi}.\n";
14 print "What is yellow? ";
19
kurotsuki

grepは、このジョブに適したツールです。

my @all_matches = grep { $fruit{$_} eq 'yellow' } keys %fruit;
print("$_ ") foreach @matching_keys;

my ($any_match) = grep { $fruit{$_} eq 'yellow' } keys %fruit;
21
socket puppet

一方向のハッシュで効率的に行うのは簡単ではありません。ハッシュの要点は、キーを値(または、カバーの下を見ている場合は、値の位置)に変換することです。すべての値を徹底的に検索して、キーを収集しますが、ハッシュルックアップほど効率的ではありません。

逆の方向に進むために、効率的にのように、双方向ハッシュを検討することをお勧めします。

%fruit = (
    'Apple' => ['red','green'],
    'kiwi' => 'green',
    'banana' => 'yellow',
);
%antifruit = (
    'red' => 'Apple',
    'green' => ['Apple','kiwi'],
    'yellow' => 'banana',
);
print "The Apple is @{$fruit{'Apple'}}.\n";
print "The kiwi is $fruit{'kiwi'}.\n";
print "A yellow thing is $antifruit{'yellow'}.\n";
2
paxdiablo
sub find_key { 
    my ( $h, $value ) = @_;
    while ( my ( $k, $v ) = each %$h ) { 
        return $k if $v eq $value;
    }
    return;
}

したがって、次のように呼び出すことができます。

find_key( \%fruit, 'yellow' );
1
Axeman

一部の値は配列なので、それを確認する必要があります。

呼び出し:

my @fruit = getfruit(\%fruit, $colour);

サブルーチン:

sub getfruit {
    my ($fruit, $col) = @_;
    my @result;
    for my $key (keys %$fruit) {
        if (ref $fruit->{$key} eq 'ARRAY') {
            for (@{$fruit->{$key}}) {
                Push @result, $key if /^$col$/i;
            }
        } else {
            Push @result, $key if $fruit->{$key} =~ /^$col$/i;
        }
    }
    return @result;
}

Eqの代わりに正規表現を使用することはオプションです。Yellowyellowは異なるキーと見なされるため、同じケースを維持することに注意してください。

1
TLP

あなたの例には無名配列への参照があるので、長く巻き込んだforeach/ifループを実行するだけです。

my %fruit = (
  'Apple' => ['red','green'],
  'kiwi' => 'green',
  'banana' => 'yellow',
);

print "The Apple is @{$fruit{Apple}}.\n";
print "The kiwi is $fruit{kiwi}.\n";
print "What is yellow? ";

my $ele;
my $search = 'yellow';
my @match = ();

foreach $ele (keys(%fruit)) {
    if(ref($fruit{$ele}) eq 'ARRAY' and
        grep { $_ eq $search } @{ $fruit{$ele} }) {
        Push(@match, $ele);
    } elsif(!ref($fruit{$ele}) and $fruit{$ele} eq $search) {
        Push(@match, $ele);
    }
}
print join(", ", @match) . "\n";
0
Drav Sloan