Schrift
[thread]6158[/thread]

Reihenfolge in einem Hash: haben "keys" und "values" die gleiche?

Leser: 1


<< |< 1 2 >| >> 12 Einträge, 2 Seiten
ronald
 2004-03-22 14:44
#81188 #81188
User since
2003-08-15
76 Artikel
BenutzerIn
[default_avatar]
Neulich sah ich ein Code-Schnipsel, bei dem sowohl auf die keys als auch auf die values zugegriffen wurde:
Code: (dl )
1
2
3
4
5
           my $sql = "INSERT INTO db (";
          $sql .= join", ", keys( %{$ref} );
          $sql .= ") VALUES ('";
          $sql .= join", ",values( %{$ref} );
          $sql .= "')";


Die Reihenfolge, in der die Funktion keys die Werte liefert ist ja nicht festgelegt.
Für den SQL-Befehl ist es aber wichtig, dass keys und values zusammenpassen.

Frage: Ist das sicher gestellt?
Relais
 2004-03-22 15:10
#81189 #81189
User since
2003-08-06
2244 Artikel
ModeratorIn
[Homepage] [default_avatar]
Natürlich nicht. Hashes sind nicht sortiert. Seit kurzem sind sie es beinahe garantiert nicht mehr. Muß die Reihenfolge passen, mußt Du eben die Values als $ref->{$key} ansprechen.
Erst denken, dann posten --
26. Deutscher Perl- u. Raku -Workshop 15. bis 17.04.2024 in Frankfurt/M.

Winter is Coming
dominicn
 2004-03-22 15:28
#81190 #81190
User since
2003-08-08
327 Artikel
BenutzerIn
[default_avatar]
doch, es funktioniert so. solange du zwischen den beiden aufrufen den hashinhalt nicht aenderst jedenfalls.

kleines (hässliches) beispielprogramm:
Code: (dl )
1
2
3
4
5
6
%hash = ();
for (1..10) {
$hash{$_} = $_*$_;
}

print "keys: ", join " ", keys %hash, "\n", "values: ", join " ", values %hash;


und http://www.perldoc.com/perl5.6.1/pod/func/values.html sagt das auch:

Quote
Returns a list consisting of all the values of the named hash. (In a scalar context, returns the number of values.) The values are returned in an apparently random order. The actual random order is subject to change in future versions of perl, but it is guaranteed to be the same order as either the keys or each function would produce on the same (unmodified) hash.
Taulmarill
 2004-03-22 15:28
#81191 #81191
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
also auf meinem perl 5.8.0 ist die reienfolge von keys und values identisch. is auch klar, weil perldoc definiert
Code: (dl )
1
2
    for (values %hash) 	      { s/foo/bar/g }   # modifies %hash values
for (@hash{keys %hash}) { s/foo/bar/g } # same

also, solange die reienfolge der keys aufrufe bei jedem aufruf gleich is, wird das funktionieren.

Aber(!) meiner meinung nach is das kein guter style. Will man hier auf nummer sicher gehen, kann man folgendes verwenden:
Code: (dl )
1
2
@keys = keys %hash; 
@values = @hash{@keys};
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Relais
 2004-03-22 16:49
#81192 #81192
User since
2003-08-06
2244 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=dominicn,22.03.2004, 14:28]doch, es funktioniert so. solange du zwischen den beiden aufrufen den hashinhalt nicht aenderst jedenfalls.[/quote]
Nein, tut es nicht. Falls doch, ist es ein Versions- und Hardware+Betriebssystemsbedingter Zufall!

Spätestens Perl 5.8.1 garantiert Dir (nahezu...*), daß es nicht mehr funktionieren wird. Aktuelle stabile Perl-Version ist jedoch schon 5.8.3, also Obacht.

*) Die Zufallswarscheinlichkeit ist dann sehr sehr sehr klein.
Erst denken, dann posten --
26. Deutscher Perl- u. Raku -Workshop 15. bis 17.04.2024 in Frankfurt/M.

Winter is Coming
Relais
 2004-03-22 16:55
#81193 #81193
User since
2003-08-06
2244 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=Taulmarill,22.03.2004, 14:28]also auf meinem perl 5.8.0 ist die reienfolge von keys und values identisch.[/quote]
Das ist ein Zufall. Ab 5.8.1 passiert das nicht mehr (...erkennbar häufig).

Dein Beispiel basiert aber auch gar nicht auf einer notwendigen Reihenfolge.
Quote
also, solange die reienfolge der keys aufrufe bei jedem aufruf gleich is, wird das funktionieren.

Das ist sie aber nicht.
Quote
Aber(!) meiner meinung nach is das kein guter style. Will man hier auf nummer sicher gehen, kann man folgendes verwenden:
Code: (dl )
1
2
@keys = keys %hash; 
@values = @hash{@keys};

Und das ist ein guter Plan!
Erst denken, dann posten --
26. Deutscher Perl- u. Raku -Workshop 15. bis 17.04.2024 in Frankfurt/M.

Winter is Coming
ptk
 2004-03-22 17:06
#81194 #81194
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Nein, Relais, das stimmt nicht. Zwar stimmt es, dass keys() zwischen mehreren Perl-Aufrufen andere Ergebnisse liefert. Aber in perldoc -f values steht ganz klar, dass
Quote
but it is guaranteed to be the same order as either the
"keys" or "each" function would produce on the same (unmodified)
hash.

Und darauf kann man sich fuer alle Perl5-Versionen in Vergangenheit und Zukunft verlassen.
Relais
 2004-03-22 17:25
#81195 #81195
User since
2003-08-06
2244 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=ptk,22.03.2004, 16:06]Nein, Relais, das stimmt nicht. Zwar stimmt es, dass keys() zwischen mehreren Perl-Aufrufen andere Ergebnisse liefert. Aber in perldoc -f values steht ganz klar, dass
Quote
but it is guaranteed to be the same order as either the
"keys" or "each" function would produce on the same (unmodified)
hash.

Und darauf kann man sich fuer alle Perl5-Versionen in Vergangenheit und Zukunft verlassen.[/quote]
Ui, da hast Du recht, das ist dann auch in 5.8.3 der Fall.

Der Text geht so weiter:
Quote
Since Perl 5.8.1 the ordering is different even between different runs of Perl for security reasons (see "Algorithmic Complexity Attacks" in perlsec)


Will heißen, innerhalb ein und desselben Aufrufs von Perl bleibt die Reihenfolge fest. Sehr gut zu wissen @ptk.
Erst denken, dann posten --
26. Deutscher Perl- u. Raku -Workshop 15. bis 17.04.2024 in Frankfurt/M.

Winter is Coming
Taulmarill
 2004-03-22 17:42
#81196 #81196
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
--- edit ---
hab den letzten beitrag von Relais noch nicht gesehen als ich untenstehendes geschrieben hab
--- /edit ---

Relais: ich hab jetz die faxen dicke. ich weiss ja nich was du da für ne perl version hast, aber ich hab mir jetzt mal die aktuelle 5.8.3 für meine Sun gezogen und installiert.
so, jetzt teste ich mal folgenden code:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
use strict;
use warnings;

my %hash;
for ( 1 .. 20 ) { $hash{$_}=$_ }

for ( 1 .. 10 ) {
print"values: ";print values %hash;print"\n";
print"keys: ";print keys(%hash);print"\n";
print "\n";
}

und bekomme folgenden output:
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
values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105

values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105

values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105

values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105

values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105

values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105

values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105

values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105

values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105

values: 1171721181613639122014158419105
keys: 1171721181613639122014158419105


wie du sehen kannst ändert sich die reienfolge der werte zwischen den aufrufen der key bzw value funktion _nicht_.

wenn du ein anderes ergebniss hast, dann poste bitte den benchmark-code.\n\n

<!--EDIT|Taulmarill|1079970410-->
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Relais
 2004-03-22 18:06
#81197 #81197
User since
2003-08-06
2244 Artikel
ModeratorIn
[Homepage] [default_avatar]
@Taulmarill: hoffentlich ärgerst Du Dich nicht nur. Ich bin jedenfalls beeindruckt, daß Du Dir Mühe gegeben hast, und meinen Beitrag erfolgreich durch ein Beispiel widerlegt hast.

Nebenbei hast Du so noch Dein Perl geupgradet, das kann nicht schaden!
Erst denken, dann posten --
26. Deutscher Perl- u. Raku -Workshop 15. bis 17.04.2024 in Frankfurt/M.

Winter is Coming
<< |< 1 2 >| >> 12 Einträge, 2 Seiten



View all threads created 2004-03-22 14:44.