¿Cómo puedo ver si un hash de Perl ya tiene una clave determinada?


Tengo un script Perl que cuenta el número de ocurrencias de varias cadenas en un archivo de texto. Quiero ser capaz de comprobar si una determinada cadena todavía no es una clave en el hash. ¿Hay una mejor manera de hacer esto en conjunto?

Esto es lo que estoy haciendo:

foreach $line (@lines){
    if(($line =~ m|my regex|) )
    {
        $string = $1;
        if ($string is not a key in %strings) # "strings" is an associative array
        {
            $strings{$string} = 1;
        }
        else
        {
            $n = ($strings{$string});
            $strings{$string} = $n +1;
        }
    }
}
Author: Peter Mortensen, 2009-06-16

5 answers

Creo que para verificar si existe una clave en un hash, simplemente haga

if (exists $strings{$string}) {
    ...
} else {
    ...
}
 105
Author: cpjolicoeur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-16 20:05:53

Desaconsejaría usar if ($hash{$key}) ya que no hará lo que espera si la clave existe pero su valor es cero o vacío.

 10
Author: RET,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-18 07:00:34

Bueno, todo tu código puede limitarse a:

foreach $line (@lines){
        $strings{$1}++ if $line =~ m|my regex|;
}

Si el valor no está allí, el operador ++ asumirá que es 0 (y luego incrementará a 1). Si ya está allí, simplemente se incrementará.

 9
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-18 06:14:42

Supongo que este código debería responder a tu pregunta:

use strict;
use warnings;

my @keys = qw/one two three two/;
my %hash;
for my $key (@keys)
{
    $hash{$key}++;
}

for my $key (keys %hash)
{
   print "$key: ", $hash{$key}, "\n";
}

Salida:

three: 1
one: 1
two: 2

La iteración se puede simplificar a:

$hash{$_}++ for (@keys);

(Véase $_ en perlvar.) E incluso puedes escribir algo como esto:

$hash{$_}++ or print "Found new value: $_.\n" for (@keys);

Que informa de cada clave la primera vez que se encuentra.

 6
Author: zoul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-16 20:13:13

Puedes ir con:

if(!$strings{$string}) ....
 -1
Author: AJ.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-07 17:44:16