Perl 6将split函数的输出解释为整数列表/数组

7
say "1 10".split(" ") 

返回 (1,10)

当我将这些1和10 作为参数传递给序列运算符[...]

say [...] "1 10".split(" ")

当使用split函数时,返回值为字符串,因此只返回了(1)而不是应该返回的(1 2 3 4 5 6 7 8 9 10)。如何解决这个问题呢?

谢谢。


第三个数字放在哪里?顺便说一下,say [...] "1 10".split(" ").Seq 不行。它只返回 (1),而期望的是返回 (1 2 3 4 5 6 7 8 9 10) - Terry
"1 10".split(" ") 返回一个序列 -- 我使用 (1,10).Seq 来使其等效。至于第三个数字放在哪里:这不像我建议的那样工作,请忽略。 - ugexe
1
你的代码正在使用你展示的操作符(省略号或3个点,...),但那不是 Range 操作符。中缀 ... 是序列操作符。它在左侧接受一个或多个初始值以及可选的生成器,右侧是一个智能匹配的结束值,并构造出一个 Seq。此外,还有一个中缀2点范围操作符,它构造出一个 Range。请参考:序列操作符和范围操作符。 - raiph
它是三个点,我的意思是不包含三个点的特殊字符。但我现在尝试了特殊字符 ,它对结果没有影响,即我仍然需要在目标序列 (1 2 3 4 5 6 7 8 9 10) 中间加上 +<< hyperop 才能得到。 - Terry
1
没错。三个点的意思与特殊省略号字符完全相同。它们是别名操作符。我的观点是,你称它为“范围”运算符,但在P6中,范围是一个与序列不同的特定事物,并且有一个范围运算符,它是两个点,而不是三个。无论如何,我看到你已经编辑了你的问题,称它为序列操作符,所以现在一切都解决了。 :) - raiph
2个回答

7

如果您想要数字行为,则将其强制转换为数字:

say [...] +<< "1 10".split(" "); # (1 2 3 4 5 6 7 8 9 10)

这里使用了 << 超运算符,将数值强制转换(前缀 +)应用于 split 生成的序列中的每个元素。


关于以 字符串 为端点的序列和范围行为:


你写的代码等价于:

put gist "1"..."10";

(say 相当于 put gist。)

"1"..."10"gist(1)

那是因为 List.new("1")gist 就像 List.new("a")gist 一样,都是 (a)

"1"..."10" 求值为 List.new("1")

为什么呢?我还不确定,但我正在探索可用的信息。

我们从文档开始。中缀操作符 ...文档说:

默认生成器是 *.succ*.pred,具体取决于端点的比较结果

好的:

say "1" cmp "10"; # Less

这可能意味着该序列开始调用*.succ

然后:

say "1".succ;     # 2

并且:

say "2" cmp "10"; # More

似乎这导致序列在“1”后立即终止,而没有包括“2”并继续。


我正在继续搜索错误队列并检查@wamba ++在其回答中链接到上面链接的SO“为什么Perl 6序列' A'… 'AA'只有一个元素?”周围的代码。


谢谢你的回答。它起作用了。所以,超级运算符解决了问题,这很好。我想知道它如何将split的“1 10”输出解释为一个(1),现在我有了想法。 - Terry
哎呀,我忘记勾选那个答案了。Håkon的回答最先到达并且基本上解决了问题,但是我还是没有将其勾选为答案,不知道为什么。然后你提供了详细的回答,我将其应用到了我的代码中。我想可能是因为我一直在调试代码,所以忘记勾选答案了。因为你的回答既解决了问题,同时又解释了Perl 6的工作原理,所以它是更好的答案,我将其勾选为答案 :) - Terry

4

通常情况下,raiph给出了正确的答案,但是我认为他忽略了为什么它确实不起作用的原因。 主要原因是[]是一个reduce运算符,除非作为副作用,否则它不会将括号内的内容视为中缀运算符。例如,以下代码可以正常工作:

say [+] <4 8>.words; # OUTPUT: «12␤»

只有因为有两个组件,且对它们应用了 [] 的 reduce,才会产生相同的效果。对于 ... 也是如此。

say [...] <4 8>.words; # OUTPUT: «(4 5 6 7 8)␤»

然而,这不是您要寻找的。您有两个操作数,一个单一运算符,您想调用运算符本身。当然,您可以通过使用其完全限定名称来实现。

say infix:<...>( | <3 5>.words ); # OUTPUT: «(3 4 5)␤»

当然,只要您将参数(使用|)压成中缀操作符的签名匹配即可。

像往常一样,TIMTOWTDI。所以请按照最适合您的方式进行操作。


1
它不起作用的真正原因并不是你想的那样。say infix:<...>( | <1 10>.words ); # OUTPUT: «(1)␤»演示了问题仍然存在于您对语法的改写中。这与我链接到的'A' ... 'AA'相同。但是,我的答案到目前为止有点匆忙和神秘。我计划在接下来的一天左右改进它,一旦我感觉已经收集了相关的错误报告、问题、IRC和设计文档讨论(特别是由Larry)以及Rakudo代码行,并且可以将其提炼出来,尽可能清晰地解释它。 - raiph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接