Perl: Zufälligen Schlüssel/Key eines Hash

Friday, August 4, 2017

Auf einen zufälligen Schlüssel eines Hash, kann man mit der Funktion keys zugreifen. Die Funktion keys, gibt alle Schlüssel eines Hash, als Liste zurück, von der dann ein Wert zufällig abgefragt werden kann:

#!/usr/bin/perl

my %alphabet = (
    A => 1,
    B => 2,
    C => 3,
    D => 4,
    E => 5,
    F => 6,
    G => 7,
    H => 8,
    I => 9,
    J => 10,
    K => 11,
    L => 12,
    M => 13,
    N => 14,
    O => 15,
    P => 16,
    Q => 17,
    R => 18,
    S => 19,
    T => 20,
    U => 21,
    V => 22,
    W => 23,
    X => 24,
    Y => 25,
    Z => 26,
);

my @keys = keys %alphabet;

# zufälliger Key

my $buchstabe = $keys[ rand @keys ];
my $position  = $alphabet{$buchstabe};

printf "Der Buchstabe %s, ist der %i. im Alphabet.\n", $buchstabe, $position;

Es ist auch möglich, direkt auf einen zufälligen Wert eines Hash zuzugreifen. Das funktioniert, analog mit der Funktion values:

my @values = values %alphabet;
print $values[ rand @values ] . "\n";

PS: In den Kommentaren, hat Christian eine etwas schnellere Möglichkeit aufgezeigt:

my @list = %alphabet;
my $random_key = $list[(1|rand@list) -1];
my $random_val = $list[1|rand@list];

Das bitweise ODER mit 1 sorgt dafür, dass das letzte Bit des Ergebnisses von rand auf 1 gesetzt wird. Dadurch entsteht immer eine ungerade Zahl (1|0 => 1, 1|1 => 1, 1|2 => 3, 1|3 => 3, …). Es wird also nur auf ungerade Indizes des Arrays zugegriffen, wo in diesem Fall die Values abgelegt sind. Da dabei immer eine Zahl größer 0 generiert wird, kann mit einem einfachen -1 immer auf die geraden Indizes mit den Keys zugegriffen werden.

  1. Marius

    Saturday, August 5, 2017 - 08:15:01

    Moin,

    Keine Einwände gegen den Code, etwas überrascht hat mich der Einsatz von Perl an sich. Andere Sprachen, andere Sitten :

    {a,b,c,d,e,f,g,h,i,j,k,l,m,n…usw. z}[Math.random(26)]

    “a:b:c:…:z”.split(”:”)[Math.random(26)];

    Perl ist halt umständlich ;)

  2. inne

    Saturday, August 5, 2017 - 14:26:47

    Hallo Marius,

    das Beispiel ist nur zu Anschauung und dafür wohl schlecht von mir gewählt.

    Es geht nicht darum einen zufälligen Buchstaben zu bekommen, sondern einen zufälligen Schlüssel eines Hash.

  3. Christian

    Saturday, August 5, 2017 - 19:38:27

    Man könnte den Hash auch gleich als Liste verarbeiten:

    #!/usr/bin/env perl
    use strict;
    use warnings;

    my %hash;
    @hash{”A” .. “Z”} = (1 .. 26);
    my @list = %hash;
    my $random_key = $list[(1|rand@list) -1];
    my $random_val = $list[1|rand@list];

  4. inne

    Monday, August 14, 2017 - 13:45:04

    Hallo Christian,

    dein Ansatz ist sogar schneller. Nur ist mir die Syntax hier unbekannt. Das $list[(1|rand@list) -1]; und $list[1|rand@list]; müsstest du erklären!

  5. Christian

    Monday, August 14, 2017 - 21:56:08

    Das bitweise ODER mit 1 sorgt dafür, dass das letzte Bit des Ergebnisses von “rand” auf 1 gesetzt wird. Dadurch entsteht immer eine ungerade Zahl (1|0 => 1, 1|1 => 1, 1|2 => 3, 1|3 => 3, …). Es wird also nur auf ungerade Indizes des Arrays zugegriffen, wo in diesem Fall die Values abgelegt sind. Da dabei immer eine Zahl größer 0 generiert wird, kann mit einem einfachen “-1” immer auf die geraden Indizes mit den Keys zugegriffen werden.