Schrift
[thread]6943[/thread]

each-operator reseten?

Leser: 1


<< |< 1 2 >| >> 13 Einträge, 2 Seiten
supersucker
 2005-04-30 17:57
#54333 #54333
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
hi,

hab einen hash der als schlüssel integer zahlen enthält und als value
wieder einen hash mit (unter anderem) float-zahlen.
nun möchte ich mir aus dem hash die 10 einträge mit den höchsten values rausholen, dies mach ich auf folgende (zugegebenermaßen ziemlich naive) art:

ich durchlaufe den kompletten hash, hol mir das element mit dem höchsten wert, pushe das auf ein array, und lösche das entsprechende hash-element, und das eben 10 mal.

dazu folgender code:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for my $i (1..$numberOfBestFrags)
{
our $index = 0;
our $maxGoodness = 0;

while(($key, $value) = each %fragmentResultSetH)
{
if($value{goodness} > $maxGoodness)
{
$maxGoodness = $value{goodness};
$index = $key;
} &nbsp
;
}
push @tenBestFrags, $fragmentResultSetH{"$index"};
delete $fragmentResultSetH{"$index"};
}


merkwürdigerweise klappt dies nun nur im ersten durchlauf der for-schleife, laufe ich das zweite, dritte usw. mal drüber, krieg ich immer folgende fehlermeldung:

Code: (dl )
Use of uninitialized value in numeric gt (>) at /root/development/eclipse/eclipse/workspace/PDB_FRAGMENT_LIB/bin/PDBQuery.pl line 436, <FILE> line 13484.


versteh ich nicht, weil wenn ich in der for-schleife folgende print-anweisungen einfüge:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
for my $i (1..$numberOfBestFrags)
{
print "for loop nr. $i \n";
my $nrOfKeys = scalar keys %fragmentResultSetH;
print "nr of keys = $nrOfKeys \n";
my $nrOfvalues = scalar values %fragmentResultSetH;
print "nr of values = $nrOfvalues \n";

....rest vom code wie oben........

}


dann sehe ich dass der code beim ersten durchlauf das tut was er soll, nämlich das grösste element (bzw. der hash mit dem grössten element) wird auf ein array gepusht und anschliessend aus dem hash entfernt...

bei jedem weiteren durchlauf der for-schleife jedoch bleibt die anzahl der keys und der values genau der gleiche, das sieht bei mir in der ausgabe z.B. so aus:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for loop nr. 1
nr of keys = 35
nr of values = 35

for loop nr. 2
nr of keys = 34
nr of values = 34

for loop nr. 3
nr of keys = 34
nr of values = 34

for loop nr. 4
nr of keys = 34
nr of values = 34

usw....


und ich erhalte ab dem zweiten for-durchlauf obigen erwähnten fehler, dass ich in dem grösser-vergleich einen undefinierten wert verwende...

woran kann das denn liegen? für mich sieht der code soweit ok aus, deswegen hab ich drauf getippt, dass vielleicht der each-operator nicht reseted wird...

im kamel-buch von larry wall steht aber dazu:

Quote
Der each-operator kann zurückgesetzt werden, indem alle Elemente im Hash gelesen werden oder indem man keys %hash oder values %hash evaluiert.


ich dachte genau das würde ich tun.......
oder liegt der fehler ganz woanders?

danke im voraus für jede hilfe...
supersucker
 2005-04-30 18:01
#54334 #54334
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
P.S.:
das alleinstehende semikolon im ersten code-beispiel hab ich nicht eingegeben und steht so nicht im source-code, wurde aber jedesmal eingefügt wenn ich die vorschau betätigt habe und ich habs nicht wegbekommen....(und woran das wohl liegen kann....)
esskar
 2005-04-30 18:28
#54335 #54335
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
benutz mal "my" anstatt "our"
supersucker
 2005-04-30 18:40
#54336 #54336
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
hmm,

hab ich gerade gemacht, also:

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
for my $i (1..$numberOfBestFrags)
{
print "for loop nr. $i \n";
my $nrOfKeys = scalar keys %fragmentResultSetH;
print "nr of keys = $nrOfKeys \n";
my $nrOfvalues = scalar values %fragmentResultSetH;
print "nr of values = $nrOfvalues \n";

my $index = 0;
my $maxGoodness = 0;

while(($key, $value) = each %fragmentResultSetH)
{
if($value{goodness} > $maxGoodness)
{
$maxGoodness = $value{goodness};
$index = $key;
} &nbsp
;
}
push @tenBestFrags, $fragmentResultSetH{"$index"};
delete $fragmentResultSetH{"$index"};

}


krieg immer noch die fehlermeldung wegen dem uninitialisierten wert, und anzahl der schlüssel und werte bleibt immer noch gleich....

noch irgendwelche ideen?
oder gibt es vielleicht einen schlaueren weg aus einem Hashofhashes die 10 hashes mit den grössten werten auszulesen?

thx
supersucker
 2005-04-30 18:40
#54337 #54337
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
Wenn ich aus dem ">" ein ">=" mache, krieg ich noch die fehlermeldung, jedoch löscht er die jeweiligen hashes, der counter für key/value geht also nach unten, nur warum?
ich sehe einfach keinen fehler in dem code, bzw. sehe ich keinen grund warum er beim ändern ">" nach ">=" auf einmal löscht, das sollte er auch so tun.....
muss ich den each-operator vielleicht explizit reseten?\n\n

<!--EDIT|supersucker|1114872443-->
pKai
 2005-04-30 19:47
#54338 #54338
User since
2005-02-18
357 Artikel
BenutzerIn
[default_avatar]
$value in der while Schleife kann kein Hash sein, höchsten ein Hashref.
In dem Fall müsste der Bezug auf den 'goodness'-Wert:
Code: (dl )
$value->{goodness}
lauten.\n\n

<!--EDIT|pKai|1114876129-->
I sense a soul in search of answers.
supersucker
 2005-04-30 20:55
#54339 #54339
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
danke für den hinweis, habs jetzt folgendermassen (sozusagen idiotensicher) gemacht:

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
28
29
30
31
32
33
34
35
for my $i (1..$numberOfBestFrags)
{
my $index = 0;
my $maxGoodness = 0;

for our $firstHashKey (keys %fragmentResultSetH)
{
for our $secondHashKey (keys %{ $fragmentResultSetH{$firstHashKey} } )
{
if($secondHashKey =~ m/goodness/)

{

my $tmp = $fragmentResultSetH{$firstHashKey}{$secondHashKey};

if($tmp > $maxGoodness)

{

$maxGoodness = $tmp;

$index = $firstHashKey;



}

}
}
}

push @tenBestFrags, $fragmentResultSetH{"$index"};
delete $fragmentResultSetH{"$index"};

}


ich versteh zwar nicht die syntax von

Code: (dl )
for our $secondHashKey (keys %{ $fragmentResultSetH{$firstHashKey} } )

aber jetzt tut der code zumindest das was er soll.......:-)
esskar
 2005-04-30 21:21
#54340 #54340
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
wieso benutzt du immer our?
supersucker
 2005-04-30 22:25
#54341 #54341
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
gute frage.......

übertreibs manchmal gern ein bisschen mit globalen variablen......
bin gerade dabei es mir abzugewöhnen, und habs im code schon geändert
coax
 2005-04-30 22:40
#54342 #54342
User since
2003-08-11
457 Artikel
BenutzerIn
[default_avatar]
Wie waer's denn mit einer ,Schwartzian Transform'-Loesung ?
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/perl

 use strict;
 use warnings;

 my %scores = (
     134    => { Goodness => 10 },
     4273   => { Goodness => 3 },
     36285  => { Goodness => 6 },
     9284   => { Goodness => 2 },
 );

 my $best_of = 2;  # Die besten ... {zwei}

 my @sorted_scores =  map { $_->[1] }
                      sort { $b->[0] <=> $a->[0] }
                      map { [$scores{$_}->{Goodness}, $_ ] } keys %scores;

 print "$_\n" for @sorted_scores[0 .. $best_of - 1];


Mehr ueber Schwartzian Transform findest zum Beispiel auf Start's Seite.
,,Das perlt aber heute wieder...'' -- Dittsche
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2005-04-30 17:57.