Hash sortieren?
betatexter
- perl
0 mrjerk0 betatexter
0 hotti
Hallo!
Ich habe ein Array, was so gebildet wird:
@{$temphash{$Id}} = ($titel,$autor,$preis,$erscheinungsjahr);
Ich möchte am Ende ich eine Liste von $Id erhalte, die nach Preis sortiert ist.
Geht das?
Vielen Dank,
Bastian
Hallo,
@{$temphash{$Id}} = ($titel,$autor,$preis,$erscheinungsjahr);
Ich möchte am Ende ich eine Liste von $Id erhalte, die nach Preis sortiert ist.
Geht das?
Ja. Du kannst der Perl-Funktion sort eine Funktion übergeben, die zum Vergleichen zweier Elemente in Deiner Liste benutzt wird. Siehe dazu Beispiel 2 im o.g. Link.
Du musst also nur eine Funktion bauen, die die Preise zweier Elemente in der Liste vergleicht.
Viele Grüße,
Jörg
die zum Vergleichen zweier Elemente in Deiner Liste benutzt wird. Siehe dazu Beispiel 2 im o.g. Link.
Hm, aber wird in dem Listing 2 nicht ein einfaches Array sortiert und nicht ein mehrdimensionales und schon gar nicht ein Hash?
Hab mir das mal angeschaut und komme auch schon gar nicht klar damit, was "$a" und "$b" sind. So wie ich das verstehe, sind das einfache "Platzhalter" für die einzelnen Elemente der eindimensionalen Liste, also es wird einfach eine Art Bubble-Sort durch alle Elemente gemacht.
In meiner Anfrage will ich ja aber immer genau eine Spalte betrachten und dies über alle Zeilen des Hashs.
Oder verstehe ich etwas vollkommen falsch?
Danke
Hi,
Hab mir das mal angeschaut und komme auch schon gar nicht klar damit, was "$a" und "$b" sind.
Zwei Elemente, die verglichen werden sollen, um zu bestimmen, wie sie einzusortieren sind.
So wie ich das verstehe, sind das einfache "Platzhalter" für die einzelnen Elemente der eindimensionalen Liste, also es wird einfach eine Art Bubble-Sort durch alle Elemente gemacht.
Ja.
In meiner Anfrage will ich ja aber immer genau eine Spalte betrachten
Dann betrachte diese „Spalte“ - in dem du auf den Inhalt dieser Spalte des Elementes a und den Inhalt dieser Spaltes des Elementes b zugreifst, und diese Inhalte vergleichst.
und dies über alle Zeilen des Hashs.
Darum kümmert sich sort selber. Deine Aufgabe ist es nur, eine Subroutine anzugeben, die zwei Elemente, die sich übergeben bekommt, „vergleicht“ und zurückgibt, wie diese beiden Elemente in der Ordnung einzusortieren sind, d.h. ob das erste „größer“ oder „kleiner“ als das zweite sein soll, bzw. ob beide „gleich“ sind.
Das Vergleichs*kriterium* legst du in deiner Subroutine selber fest.
MfG ChrisB
hi Chris,
das P. ist übrigens gelöst, war ein Crosspost (anderes Forum), aber das nurmalso nebenbei ;)
Darum kümmert sich sort selber. Deine Aufgabe ist es nur, eine Subroutine anzugeben,
In diesem Fall ist das nicht notwendig, genausowenig wie 'meine' Schwartzsche Transformation (1). Eine Subroutine oder die Schwartzsche Transformation wird nur erforderlich, wenn das Sortierkriterium in der Liste nicht direkt adressierbar ist, was hier jedoch der Fall ist:
Wir haben einen Hash mit den IDs und die jeweiligen Werte sind Array-Referenzen, wobei das Sortierkriterium in der Arrayreferenz auf dem Index [2] liegt und numerisch ist (der Preis).
Das Sortierkriterium 'Preis' ist somit adressierbar wie folgt:
$preis = $hash{$id}->[2]; # nur zum Verständnis
Zum Sortieren genügt tatsächlich die sort()-Funktion, iteriert wird über die Keys des Hash wie folgt:
my @IDs = sort{$temphash{$a}->[2] <=> $temphash{$b}->[2]} keys %temphash;
Die Schwartzsche Transformation ist dennoch nicht uninteressant. In dem zuunterst liegenden map{} wird ein anonymes Array erzeugt und das Sortierkriterium auf einen bestimmten Index gelegt. Hier an dieser Stelle käme eine Subroutine rein, die ggf. das Sortierkriterium aus den Werten des Hash ermittelt, z.B. eine Stringfunktion oder eine Regular-Expression.
Hotti
das P. ist übrigens gelöst, war ein Crosspost (anderes Forum), aber das nurmalso nebenbei ;)
Yepp, vielen Dank!
Das Sortierkriterium 'Preis' ist somit adressierbar wie folgt:
$preis = $hash{$id}->[2]; # nur zum Verständnis
Ja, das habe ich bis gestern nicht gekannt und hat mir sehr geholfen.
Vielen Dank an alle hier Beteiligten.
hi,
@{$temphash{$Id}} = ($titel,$autor,$preis,$erscheinungsjahr);
Ich möchte am Ende ich eine Liste von $Id erhalte, die nach Preis sortiert ist.
Geht das?
Wir nehmen die Schwartzsche Transformation, da wird das Sortierkriterium auf eine bestimmt Position in einem anonymen Array gelegt, zum Verstehen, lese den Code von unten nach oben:
use strict;
use warnings;
my %temphash = ();
# Einträge zum Testen
# Für das Array eine Referenz, Preis in [2]
$temphash{'1a'} = ['A-Test','Anton','99','1978'];
$temphash{'2b'} = ['B-Test','Berta','11','1975'];
$temphash{'3c'} = ['C-Test','Cäasar','33','1980'];
# gesucht eine Liste mit Id's die nach Preis sortiert ist
my @IDs =
map{$_->[0]} # keys aus [0]
sort{$a->[1][2] <=> $b->[1][2]} # Sortierkriterium in [1][2]
map{[$_, $temphash{$_}]}keys %temphash; # keys in [0], ref in [1]
# Ausgabe
print join "\n", @IDs;
Hotti