2017-07-27 55 views
2

我在type : amount格式的文件,我希望把所有 行到一个哈希的键是types和值为 总和amounts

然而,似乎types如何引述影响如何 amounts的行为。有人可以解释一下吗?

这里是文件data的内容:

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

当密钥与%x<$/[0]>构造,键似乎是 正确,但这些值似乎被推入的阵列,即使我 要添加到获得总金额:

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 

同样的行为,如果密钥与<"$/[0]">构造:

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 

当键盘构建了%x{"$/[0]"},键和值 行为正确:

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 

那么,怎么来的钥匙影响值如何表现?还是我问了一个错误的问题?

回答

3

我想你对<>有什么误解。他们基本上单引号相当于:

say <"foo"> # "foo" 

所以你检查是否一个键“$/[0]”存在,它没有,然后push一个Pair到哈希用正确的双引号(虽然没有必要引用它),如果不存在,它将创建正确的密钥。

由于$0是短期的$/[0]m///使用$_默认情况下,在一个哈希不存在的键默默地Any创建的,你可以+=Any只是Perl 5中,并END块没有像您可以在南瓜”吨需要有一个块,你只有真正需要:

$ 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 

其实,细想起来,实际闻起来像一个Mixhttps://docs.perl6.org/type/Mix)。作为读者的练习留下:-)

+0

谢谢伊丽莎白Mattijsen!我现在明白了。我的错误是认为<>会用插值双引号。随着哈希键的推出,我很难找出自己的误解。我会研究袋,混合,套等,谢谢! – lisprogtor