hash-slice in schleife?

hash-slice in schleife?

am 08.04.2006 12:24:51 von Oliver Block

Hi,

die meisten kennen die Möglichkeit einen Hash mittels foreach-Schleife zu
durchlaufen:

##
%myhash = ( 'peter' => 'petra' ,
'paul' => 'paula',
'hermann' => 'hermine',
'ulrich' => 'ulrike',
'wilhelm' => 'whilhelmine');

foreach $k (keys %myhash) {
print "$k liebt $myhash{$k}\n";
}
##

Gibt es eigenlich auch eine Möglichkeit _nicht_nur_einen_ sondern _zwei_
Schlüssel pro Iteration zu erhalten?

Ich habe ein wenig probiert, bin aber bisher zu keinem Ergebnis gekommen.

Gruss,

Oliver

Re: hash-slice in schleife?

am 08.04.2006 13:43:56 von Wolf Behrenhoff

Oliver Block schrieb:
> die meisten kennen die Möglichkeit einen Hash mittels foreach-Schleife zu
> durchlaufen:
>
> foreach $k (keys %myhash) {
> print "$k liebt $myhash{$k}\n";
> }
>
> Gibt es eigenlich auch eine Möglichkeit _nicht_nur_einen_ sondern _zwei_
> Schlüssel pro Iteration zu erhalten?

Erstens: wozu?

Zweitens:
my @k=keys %myhash;
und dann einfach pro Schleifendurchlauf 2x pop machen oder 2x shift oder
einfach einen Index $i hochzählen (pro Durchlauf $i+=2) und jeweils die
Elemente $myhash{$k[$i]} und $myhash{$k[$i+1]} nehmen. Beachte den
Spezialfall, dass es eine ungerade Anzahl an Schlüsseln geben kann.

Wolf

Re: hash-slice in schleife?

am 08.04.2006 17:55:13 von Slaven Rezic

Oliver Block writes:

> Hi,
>
> die meisten kennen die Möglichkeit einen Hash mittels foreach-Schleife zu
> durchlaufen:
>
> ##
> %myhash = ( 'peter' => 'petra' ,
> 'paul' => 'paula',
> 'hermann' => 'hermine',
> 'ulrich' => 'ulrike',
> 'wilhelm' => 'whilhelmine');
>
> foreach $k (keys %myhash) {
> print "$k liebt $myhash{$k}\n";
> }
> ##
>
> Gibt es eigenlich auch eine Möglichkeit _nicht_nur_einen_ sondern _zwei_
> Schlüssel pro Iteration zu erhalten?
>
> Ich habe ein wenig probiert, bin aber bisher zu keinem Ergebnis gekommen.
>

So zum Beispiel:

my %myhash = ( 'peter' => 'petra' ,
'paul' => 'paula',
'hermann' => 'hermine',
'ulrich' => 'ulrike',
'wilhelm' => 'whilhelmine');

for %myhash.keys -> $k1, $k2 {
say "1) $k1 liebt %myhash{$k1}";
say "2) $k2 liebt %myhash{$k2}";
}

Schlechte Nachricht: das ist Perl6-Syntax.
Gute Nachricht: es funktioniert bereits mit pugs :-)

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de
Tired of using file selectors? Real programmers use the TAB key for
completion and not for jumping around. Try
http://search.cpan.org/search?mode=module&query=Tk::PathEntr y

Re: hash-slice in schleife?

am 09.04.2006 00:19:36 von Mirco Wahab

Hallo Slaven,

>>Ich habe ein wenig probiert, bin aber bisher zu keinem Ergebnis gekommen.
>
> Schlechte Nachricht: das ist Perl6-Syntax.
> Gute Nachricht: es funktioniert bereits mit pugs :-)

Perl6?

Hmmm, entweder hab ich das Problem nicht richtig
verstanden - oder man sieht die Lösung nicht so
leicht, weil sie allzu einfach ist ;-)

my %myhash = ( peter => 'petra' ,
paul => 'paula',
hermann => 'hermine',
ulrich => 'ulrike',
wilhelm => 'whilhelmine'
);

my ($k1, $k2, $v1, $v2);
my $iter =0;

while (
($k1,$v1) = each %myhash
and
($k2,$v2) = each %myhash ) {
print ++$iter, "\n";
print "$k1=$v1\n";
print "$k2=$v2\n";
}


Viele Grüße

M.

Re: hash-slice in schleife?

am 09.04.2006 12:37:46 von Maluku

Mirco Wahab schrieb:
> while (
> ($k1,$v1) = each %myhash
> and
> ($k2,$v2) = each %myhash ) {
> print ++$iter, "\n";
> print "$k1=$v1\n";
> print "$k2=$v2\n";
> }
Dann vergisst du den letzten Eintrag, wenn der Hash eine ungrade Anzahl
von keys hat, da der Teil nach dem "and" nicht wahr ist.

Mann kann auch each missbrauchen:

my %a;
@a{1..5}=(1..5);
my %keys = keys %a;
while (($k1,$k2)=each %keys) {
print "$k1 == $a{$k1}\n";
print "$k2 == $a{$k2}\n";
}


--
$_='';s%%`^.*`s;.*;uhtnmo;;a>lha~a>inu~a>fmk~a>rou~a>duM~a>b tl~s;&&&&&&;
!d1!l2!b3!i4!f5!r6q(?);e;Z``}a>&&&`sub# "1#{#"_=shift#;s^"2^"3#^;``;~`
return #"_#}``^!&&`"1(#""2)#\.`Z%x;s~Z~print~g;s/#/\\/g;
s/`(.)(.+?)`(.+?)`/s$1$2$1$3$1g\;/gsx;s;&;(.);g;y^"^$^;print ;

Re: hash-slice in schleife?

am 09.04.2006 16:29:27 von Mirco Wahab

Hallo Marc

> Dann vergisst du den letzten Eintrag, wenn der Hash eine ungrade Anzahl
> von keys hat, da der Teil nach dem "and" nicht wahr ist.

OK, stimmt.

> Mann kann auch each missbrauchen:
>
> my %a;
> @a{1..5}=(1..5);
> my %keys = keys %a;
> while (($k1,$k2)=each %keys) {
> print "$k1 == $a{$k1}\n";
> print "$k2 == $a{$k2}\n";
> }

Warum einfach, wenns auch kompliziert geht.
Hier ohne Temp-Keyarray:

my ($k1, $k2);
my $n=1;
my %h =(peter => 'petra' ,
paul => 'paula',
hermann => 'hermine',
ulrich => 'ulrike',
wilhelm => 'whilhelmine' );

while( ($k1,$k2) = keys %{{each %h, each %h}} ){
print $n++,") $k1 liebt $h{$k1} \n";
last unless $k2 ;
print $n++,") $k2 liebt $h{$k2} \n";
}


Der Trick ist, jedesmal einen Satz
von 2 Hashes über 'each' herauszupicken
und wieder in einen sub-Hash zu verwandeln,
aus dem 'keys' sich eben die keys ziehen kann.

Das ist imho der 'closest approach'
zu Slavens 'überzeugenderen' P6-Variante ;-)

Viele Grüße

M.