Raku-Steueranweisung, um numerische Zeichenfolgen als numerisch zu interpretieren

8

Ich habe einen großen Hash von Arrays,

%qual<discordant> (~ ca. 13199 Werte wie '88 .23 ', '99 .23' usw.

die von 88-100 reicht und aus Textdateien eingelesen wird,

und wenn ich drucke %qual<discordant>.minund %qual<discordant>.maxsehe, dass die Werte eindeutig falsch sind.

Ich kann dies beheben, indem ich ändere, wie die Daten aus den Textdateien eingelesen werden:

%qual{$type}.push: @line[5]

zu

%qual{$type}.push: @line[5].Num

Dies war jedoch nicht intuitiv. Ich brauchte einige Minuten, um herauszufinden, warum Raku / Perl6 zunächst eindeutig falsche Antworten gab. Es wäre sehr leicht gewesen, diesen Fehler zu übersehen. In perl5 besteht das Standardverhalten darin, diese Zeichenfolgen ohnehin wie Zahlen zu behandeln.

Es sollte eine Steueranweisung geben, um dies zum Standardverhalten zu machen. Wie kann ich das tun?

con
quelle
1
Wie wird @linegefüllt?
Elizabeth Mattijsen
@linewird aus Textdateien gefüllt,my @line = $line.split(/\s+/)
con
my @line = $line.wordswird dann schneller sein.
Elizabeth Mattijsen

Antworten:

10

Das Problem / Merkmal ist wirklich, dass in Raku beim Lesen von Zeilen aus einer Datei Zeichenfolgen (auch als Typobjekte bezeichnet Str) werden. Wenn Sie anrufen .minund .maxauf einem Array vonStr Objekten, dann wird String Semantik verwendet werden , um festzustellen , ob etwas größer oder kleiner ist.

Es gibt spezielle Werte in Raku, die sich wie Werte in Perl verhalten. In Raku werden diese " Allomorphe " genannt. Sie sind Str, aber auch Num, oder Rat, oder Int, oderComplex .

Die Syntax zum Erstellen eines geeigneten Allomorphs für einen String in $_lautet << $_ >>. Wenn Sie also die Zeile ändern, in der die Wörter lauten:

my @line = $line.words.map: { << $_ >> }

dann sind die Werte in @lineentweder Stroder IntStroder RatStr. Welches sollte machen .minund.max funktionieren, wie Sie erwarten.

Wenn Sie jedoch sicher sind, dass nur das 5. Element von @linenumerisch sein wird, ist es wahrscheinlich effizienter, das Strin eine Zahl umzuwandeln , bevor Sie es in das Array verschieben. Eine kürzere Syntax dafür wäre das Präfix a +:

%qual{$type}.push: +@line[5]

Obwohl Sie das vielleicht zu laut finden.

UPDATE: Ich hatte vergessen, dass es tatsächlich ein Sub namens gibt val, das ein nimmt Strund ein entsprechendes Allomorph davon erstellt (oder das Original zurückgibt Str). Der Code zum Erstellen @linekönnte also wie folgt geschrieben werden:

my @line = $line.words>>.&val
Elizabeth Mattijsen
quelle
1
Oft verwende ich .Numericlieber +als teilweise, um zu viele Symbole in einer Reihe zu vermeiden, aber auch, weil es ein bisschen mehr herausspringt, um zu sagen "Hey, ich brauche das als Zahl", +ist es klein genug, dass es verloren gehen kann das Mischen (dito für ~vs .Str).
user0721090601
Ich denke, dass das Standardverhalten in Raku Perl ähnlich sein sollte, dh im Grunde ist alles ein Allomorph, es ist einfacher und intuitiver. Ich denke, die Standardeinstellung sollte sein, Zeichenfolgen wie 83.44numerisch zu betrachten
con
Das Erstellen von Allomorphen ist in Raku umständlich, da Arbeit erforderlich ist, um den richtigen Allomorph-Typ erstellen zu können. Dies steht im Gegensatz zu Perl, wo diese Arbeit erledigt wird, wenn die Variable tatsächlich in einem numerischen Kontext verwendet wird, da Perl keine explizite Typisierung hat. Es ist also nicht nur eine sehr gut durchdachte Designentscheidung, nicht alles als Allomorph zu erstellen, es gibt auch Leistungsgründe, dies nicht zu tun.
Elizabeth Mattijsen
fwiw ich denke raku sollte "tun was ich meine" ... << $ _ >> ist sehr laut ... also, unabhängig von der Geschwindigkeit, können wir bitte eine Methode haben, sagen wir $ line.allo dafür? (Ja, ich weiß, ich kann eine schreiben!)
p6steve
val($line)würde es nicht für dich tun?
Elizabeth Mattijsen