in Perl sortieren

Perl Checker gesucht

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

in Perl sortieren
ich hab da folgedes problem für das ich keine effiziente loesung weis:

ich hab n array mit program namen incl. version die ca. so aussehen:
(das R und die nummer stehen jeweils für die revisions nummer)

.
.
.
HalloWelt_R0.1
HalloWelt_R0.4
HalloWelt_R1.15
HalloWelt_R1.9
WeltHallo_R0.12
WeltHallo_R0.2
WeltHallo_R5.4
.
.
.

jetzt muss ich jedes programm für sich nach versions nummern absteigend sortieren. so das es dann so aussieht:

HalloWelt_R0.1
HalloWelt_R0.4
HalloWelt_R1.9
HalloWelt_R1.15

WeltHallo_R0.2
WeltHallo_R0.12
WeltHallo_R5.4

(ich hab HalloWelt und WeltHallo nat. dann in 2 verschiedene arrays gepackt um sie dann zu sortieren.)

in nem perl buch hab ich gesehen das sowas in perl geht:

@sorted = {$a->ErsterWert <=> $b->ErsterWert || $a->ZweiterWert <=> $b->ZweiterWert} @unsorted

ErsterWert wäre bei mir der wert vor dem punkt und ZweiterWert der nach dem punkt

also zuerst nach dem ersten und dann bei gleichheit nach dem 2ten wert sortieren …
nur weis ich jetzt leider nicht wie ich wie ich das @unsorted aufbauen bzw wie ich meine daten da reinquetschen soll damit dieser sort geht.
hat da jmd ahnung von?


dem mann kann geholfen werden :wink:
die hier benutzte technik heisst unter perlern “schwartzian transform”.

#!/usr/bin/perl -w
use strict;
use Data::Dumper;

# daten holen
my @list= map {chomp; $_} <DATA>;

# berechnung von sortierinformation
@list= map {
	m/(\w+)_R(\d+)\.(\d+)/; 
	[ $_, $1, $2, $3 ]
} @list;

# sortieren
@list= sort {
	$a->[1] cmp $b->[1] ||
	$a->[2] <=> $b->[2] ||
	$a->[3] <=> $b->[3]
} @list;

# sortierinformation wieder wegschmeissen
@list= map {$_->[0]} @list;

# ausgeben
print Dumper \@list;

__DATA__
HalloWelt_R0.1
HalloWelt_R0.4
HalloWelt_R1.9
WeltHallo_R0.12
WeltHallo_R0.2
WeltHallo_R5.4
HalloWelt_R1.15

das ganze geht natürlich kürzer (und ist die übliche form der schwartzian transform):

map { $_->[0] } sort { $a->[1] cmp $b->[1] || $a->[2] <=> $b->[2] || $a->[3] <=> $b->[3] } map {m/(\w+)_R(\d+)\.(\d+)/; [ $_, $1, $2, $3 ]} map {chomp; $_} <DATA>;

wenn du fragen zu einzelnen konstrukuten hast, dann her damit!
RAUCHENDESSMILEYDAMNIT* :motz: :smiley:


ja wie geil :slight_smile: ich verstehs zwar jetzt nur so zu 50%-60% aber langsam macht das zeug sinn was ich im oreilly gelesen hab.
ich schuld dirn bier kabel!


ich bin die woche an der uni.
entweder CIP im 2ten stock oder in der bib.
wenn du willst kann ich dir die restlichen 50-40% erklären :slight_smile:


Hey kabel,

Leider habe ich dich bisher im CIP nie als kabel identifiziert, kannst du mich mal anstoßen, wenn du mich siehst?

:slight_smile:


also du holst und beschneidest die daten mit map {chomp; $_} <DATA>;

damit map {m/(\w+)_R(\d+)\.(\d+)/; [ $_, $1, $2, $3
bauste n array deren subarrays so aussehen [gesamter string, text, erste zahl ,zweite zahl]
dann sortierste das array nach den subarray elementen text || erste zahl || zweite zahl wenn ich das richtig seh … wenn du damit fertig bist veränderste das array wieder in dem du nur den den gesamten string als array elemente nimmst.
ist das richtig so ?

also diese perl syntax ist mal echter horror :frowning:


yo stimmt so.
zur syntax: sooo schlimm ist das auch nicht.

@ford: erinner mich dran wenn du mich siehst :wink:


kabel:

@buffer = map { m/.*@@((\\.*\\)+d+)$/; $1 }@buffer;

sollte doch aus diesem string

V:\jiang_main\docs\HS2001\abrechnung.doc@@\main\68@@\main\saldo\12

per

print Dumper \@buffer;

folgedes outputen:

$VAR1 = { \main\saldo\12, ...

oder? … weil ich krieg nur undefs da wo $1 stehen sollte … :frowning:

p.s. mit $2 hab ichs schon auch probiert.


ich depp hab vergessen d zu escapen … vergiss den post wieder …


Ich weiss doch nicht wer du bist :frowning: