Schrift
[thread]6901[/thread]

schlüssel im hash ermitteln

Leser: 1


<< >> 9 Einträge, 1 Seite
Froschpopo
 2005-04-17 19:52
#53872 #53872
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
mal angenommen ich kenne nur den wert eines hash-eintrags und möchte gerne den schlüssel wissen. gibts da noch eine andere möglichkeit als das ganze in einer schleife zu durchlaufen? Gibts auch sowas dass man direkt auf ein Element zugreifen kann?

also sowas wie: keys($hash{wert})
ist doch sicher nen performancekiller wenn man die ganzen elemente einzeln abarbeiten muss z.b. mit each...
Ronnie
 2005-04-17 20:02
#53873 #53873
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Hashe haben keine numerischen Indizes, ohne Schlüssel sind sie nur durch iterieren zu durchlaufen. Wenn du Indizes willst nimm Arrays.
Froschpopo
 2005-04-17 20:07
#53874 #53874
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
naja etwas aufwändig:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
my %hash = (
    "name" => "lucas"
);

my $res = get_key("lucas");

sub get_key {
    foreach (my ($key, $value) = each(%hash)) {
        return "$key\n" and last if $value eq $_[0];
    }
}
\n\n

<!--EDIT|Froschpopo|1113754230-->
sri
 2005-04-17 21:16
#53875 #53875
User since
2004-01-29
828 Artikel
BenutzerIn
[Homepage] [default_avatar]
[quote=Froschpopo,17.04.2005, 17:52]mal angenommen ich kenne nur den wert eines hash-eintrags und möchte gerne den schlüssel wissen. gibts da noch eine andere möglichkeit als das ganze in einer schleife zu durchlaufen? Gibts auch sowas dass man direkt auf ein Element zugreifen kann?

also sowas wie: keys($hash{wert})
ist doch sicher nen performancekiller wenn man die ganzen elemente einzeln abarbeiten muss z.b. mit each...[/quote]
Nein das geht nicht, liegt daran wie Hv's intern funktionieren.

Es ist naemlich ein array mit verketteten listen.

Quasi so wenn man sich es als perl struktur vorstellt (pseudocode):
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$xpvhv = {
   array => [
       {
           next => {
               next => {
                   next => {
                       # usw
                   },
                   hek => 'key3',
                   val => 'value3',
               },
               hek => 'key2',
               val => 'value2',
           },
           hek => 'key',
           val => 'value',
       },  
       {
           next => {
               # usw
           },
           hek => 'key',
           val => 'value',
       },
     ],
     # magische felder fuer iterator, index, stash etc.
};


Die position im array ergibt sich aus einer pruefsumme der keys, an die Kette wird einfach angehaengt.
Das erklaert auch warum Perl hash's so schnell sind. ;)\n\n

<!--EDIT|sri|1113758309-->
Gast Gast
 2005-04-17 22:38
#53876 #53876
Code (perl): (dl )
1
2
3
4
5
6
#!/usr/bin/perl
use warnings;
use strict;
my %a = (a => 'b', c => 'd', e => 'f');
my %b = reverse %a;
print $b{f}, "\n";

Code: (dl )
1
2
$ ./hashtest.pl
e

Beachte aber, dass du Probleme bekommst, wenn ein Value mehr als einmal vorkommt.
renee
 2005-04-18 10:36
#53877 #53877
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Und Du bekommst Schwierigkeiten, wenn die Values keine Zeichenketten sind...

z.B.:
Code: (dl )
1
2
3
4
5
6
7
#!/usr/bin/perl
use warnings;
use Data::Dumper;
use strict;
my %a = (a => 'b', c => [qw/user1 user2 user3/], e => 'f');
my %b = reverse %a;
print Dumper(\%b);


Dann ist nämlich die Array-Adresse der Schlüssel...

Code: (dl )
1
2
3
4
5
$VAR1 = {
'f' => 'e',
'b' => 'a',
'ARRAY(0x81522d8)' => 'c'
};
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
ptk
 2005-04-18 12:24
#53878 #53878
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Man koennte auch eine Tie-Loesung basteln, bei der zwei Hashes fuer die Vorwaerts- und Rueckwaertsrichtung transparent beim Einfuegen/Loeschen erzeugt werden. Siehe auch TwoDirHash (Google). Eine Tie-Loesung duerfte bei kleinen Datenmengen allerdings wegen des OO- und TIE-Overheads langsamer sein.
Taulmarill
 2005-04-18 13:50
#53879 #53879
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
ich hab mal aus langeweile ne lösung mit grep gemacht. evtl. kann das ja noch wer optimieren:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use strict;
use warnings;

my %hash = (
foo => "bar",
bar => "baz",
baz => "bar"
);

print join ", ", find_key( \%hash, 'bar' );
print "\n";

sub find_key {
my ( $hash, $val ) = @_;
grep { $$hash{$_} eq $val } keys %$hash;
}
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Crian
 2005-04-18 16:51
#53880 #53880
User since
2003-08-04
5870 Artikel
ModeratorIn
[Homepage]
user image
Wenn die Werte des Hashes paarweise disjunkt sind, kannst Du ein zweites Hash für die Gegenrichtung erstellen.

Diese Technk nutze ich öfters bei Übersetzungstabellen zwischen Codes und zugehörigen Texten. Da baue ich beim Einlesen zwei Hashes auf und kann dann später je nach benötigter Richtung das eine oder das andere Hash verwenden.\n\n

<!--EDIT|Crian|1113828737-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
<< >> 9 Einträge, 1 Seite



View all threads created 2005-04-17 19:52.