2017-07-27 3 views
2

Ich habe eine Datei im Format von type : amount und ich möchte alle die Linien in einen Hash, dessen Schlüssel setzen sind die types und die Werte sind die Summe der amounts.

Es scheint jedoch, dass, wie die types notiert beeinflusst, wie die amounts verhalten. Kann mir jemand erklären, wie? Hier

ist der Inhalt der Datei data:

food : 100.01 
gas : 50.02 
food : 20.03 
gas : 30.04 

Wenn die Tasten mit %x<$/[0]> aufgebaut sind, die Tasten scheinen korrekt zu sein, aber die Werte scheinen in ein Array geschoben werden, obwohl ich hinzufügen möchten den Gesamtbetrag zu erhalten:

home/lisprog$ cat data | perl6 -ne ' 
    state %x //= {}; 
    if $_ ~~ m/ \s* (\S+) \s* \: \s* (\d+\.\d+) \s*/{ 
     if %x<$/[0]>:exists { 
      %x<$/[0]> += ($/[1].Numeric); 
     } 
     else { 
      %x.push: "$/[0]"=>($/[1].Numeric); 
     } 
    }; 
    END { for %x.kv -> $m, $n { say "$m : $n"; } }' | sort 
food : 100.01 20.03 
gas : 50.02 30.04 

Das gleiche Verhalten, wenn die Schlüssel mit <"$/[0]"> aufgebaut sind:

cat data | perl6 -ne ' 
    state %x //= {}; 
    if $_ ~~ m/ \s* (\S+) \s* \: \s* (\d+\.\d+) \s*/{ 
     if %x<"$/[0]">:exists { 
      %x<"$/[0]"> += ($/[1].Numeric); 
     } 
     else { 
      %x.push: "$/[0]"=>($/[1].Numeric); 
     } 
    }; 
    END { for %x.kv -> $m, $n { say "$m : $n"; } }' | sort 
food : 100.01 20.03 
gas : 50.02 30.04 

Wenn die Tasten konstruiert mit %x{"$/[0]"}, die Schlüssel und Werte korrekt verhalten:

home/lisprog$ cat data | perl6 -ne ' 
    state %x //= {}; 
    if $_ ~~ m/ \s* (\S+) \s* \: \s* (\d+\.\d+) \s*/{ 
     if %x{"$/[0]"}:exists { 
      %x{"$/[0]"} += ($/[1].Numeric); 
     } 
     else { 
      %x.push: "$/[0]"=>($/[1].Numeric); 
     } 
    }; 
    END { for %x.kv -> $m, $n { say "$m : $n"; } }' | sort 
food : 120.04 
gas : 80.06 

So, wie kommt die Schlüssel beeinflussen, wie Werte verhalten? Oder habe ich eine falsche Frage gestellt?

Antwort

3

Ich denke, Sie haben ein Missverständnis darüber, was <> tut. Sie sind im Grunde das Äquivalent von Einzel Zitate:

say <"foo"> # "foo" 

Also, wenn Sie die Überprüfung ein Schlüssel ‚$/[0]‘ existiert, die es nicht tut, und dann push ein Pair auf den Hash mit dem richtigen doppelten zitiert (obwohl es unnötig ist, es dort zu zitieren), die wird den richtigen Schlüssel erstellen, wenn es noch nicht existiert.

Seit $0 ist die Abkürzung für $/[0], m/// verwendet $_ standardmäßig und nicht vorhandenen Schlüssel in einem Hash werden stillschweigend mit Any erstellt, und Sie können +=Any genau wie möglich in Kürbis Perl 5 und END Blöcke don‘ t brauchen einen Block zu haben, müssen Sie nur wirklich brauchen:

$ cat data | perl6 -ne ' 
state %x; 
%x{$0} += $1 if m/ \s* (\S+) \s* \: \s* (\d+\.\d+) \s* /; 
END for %x.kv -> $m, $n { say "$m : $n" }' | sort 

eigentlich kommen, daran zu denken, das riecht tatsächlich wie ein Mix (https://docs.perl6.org/type/Mix). Lassen Sie das als eine Übung für den Leser :-)

+0

Danke Elizabeth Mattijsen !! Ich hab es jetzt. Mein Fehler war zu denken, dass <> double quote mit Interpolation. Und mit dem Hash-Push, der den richtigen Schlüssel machte, hatte ich Mühe, mein eigenes Missverständnis herauszufinden. Ich werde in die Taschen, Mixe, Sets usw. schauen. Danke !!! – lisprogtor

Verwandte Themen