Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]13102[/thread]

Kann man Einträge schon sortiert in Hash einfügen?



<< >> 7 Einträge, 1 Seite
stelzbock
 2009-02-04 17:38
#118650 #118650
User since
2009-01-29
17 Artikel
BenutzerIn
[default_avatar]
Hi Leutz,

danke noch mal für die große Hilfe in dem Thead.

Ich bin jetzt ein paar Schritte weiter und habe da wieder ein Problemchen :)
Es gibt ein Hash der Form

{"asd92394" => [1203, 23, 3435]} usw.
D.h. Key ist eine eindeutige ID und Value ein Array. Am Ende soll dieser Hash in eine XML Datei geschrieben werden, und zwar nach einem Arrayeintrag sortiert, sagen wie mal [0]. Einfügen tu ich die Werte schon in der Richtigen Reihenfolge, nur leider verwurschtelt das Hash alles. Kann ich Perl irgendwie zwingen die Einträge auch in der selben Reihenfolge zu behalten wie ich sie einfüge?

Ich weiß ich könnte mit sort und ner Helper-Funktion sortieren. Aber das würde dazu führen, dass die 200.000 Einträge im Speicher kopiert werden, was ich nicht so schön fänd und auch länger dauern würde.

Man könnte natürlich auch gleich ein Array nehmen, aber dann kann ich nicht mehr per ID-string auf die Elemente zugreifen!

Seht ihr eine Möglichkeit das zu bewerkstelligen?

Danke und Gruß Jan!
murphy
 2009-02-04 18:02
#118651 #118651
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Ein Hash ist immer so sortiert, dass Perl die Schluessel schnell findet, nicht so, wie der Programmierer die Dinge eingefuegt hat.

Im Prinzip hast Du zwei Moeglichkeiten um sowohl eine bestimmte Sortierung als auch einen schnellen Zugriff ueber Schluessel zu haben: Entweder Du benutzt einen Binaerbaum statt eines Hashes oder Du benutzt einfach einen Hash und ein Array mit den sortierten Schluesseln parallel.

Fuer beide Varianten gibt's auch CPAN-Module, zum Beispiel CPAN:Tie::Hash::Sorted und CPAN:Tree::RedBlack.
When C++ is your hammer, every problem looks like your thumb.
stelzbock
 2009-02-04 18:17
#118652 #118652
User since
2009-01-29
17 Artikel
BenutzerIn
[default_avatar]
Hi Murphy,

danke für die Antwort!

Also aufgrund des Beispielcodes in CPAN würd ich mal darauf Tippen, das CPAN:Tie::Hash:Sorted das gleich macht wie wenn ich einfach mein Hash nehmen, und dann mit ner sort helper funktion das ganze sortiere. Da kriege ich dann auch nen neuen Array mit den Keys. Das wollte ich ja vermeiden.

Aber OK, es ist jetzt auch nicht soo schlimm, dachte nur es gibt vielleicht einn Eleganteren Weg ;)

Jan
Taulmarill
 2009-02-04 18:41
#118653 #118653
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
Alternativ könnte man auch eine andere Datenstruktur in folgender Form verwenden:
Code: (dl )
1
2
3
4
5
my @data = (
[ "key1", [ 1, 2, 3, ] ],
[ "key2", [ 4, 5, 6, ] ],
# u.s.w.
);

Da bliebe dann alles sortiert, bietet aber wieder keinen direkten Zugriff auf die Werte über den Key. Wenn du wirklich beides willst, brauchst du halt Tie::Hash::Sorted oder einen Hash und einen Array. Wobei man wahrscheinlich in einer Datenstruktur auf die Werte in der anderen referenzieren sollte anstatt alles doppelt vor zu halten.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Linuxer
 2009-02-04 18:53
#118654 #118654
User since
2006-01-27
3890 Artikel
HausmeisterIn

user image
Ich habe, wenn ich so etwas brauchte, immer CPAN:Tie::IxHash benutzt.
Vielleicht hilft es Dir.
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
Crian
 2009-02-05 10:18
#118658 #118658
User since
2003-08-04
5867 Artikel
ModeratorIn
[Homepage]
user image
Man kann Hashes nicht sortieren. Was man machen kann: Die Liste der Keys nach bestimmten Kriterien für die Ausgabe sortieren.

Siehe http://www.duehl.de/christian/perl/perlmain.html#s... und die folgenden Beispiele.
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
LanX-
 2009-02-05 14:23
#118662 #118662
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
@stelzbock: eine tie-Lösung ist die sauberste, da es aber bei dir auf Geschwindigkeit ankommt, wär der trivilae Ansatz der beste, ein normales Hash und ein Array mit den sortierten Keys.

Tie-Lösungen laufen über Perls OO-Mechanismus, das ist deutlich langsamer.
<< >> 7 Einträge, 1 Seite



View all threads created 2009-02-04 17:38.