【问题标题】:perl6 text substitution on array数组上的 perl6 文本替换
【发布时间】:2019-04-23 17:07:34
【问题描述】:

我正在尝试对整个数组应用文本替换。

但是,当我尝试更改数组时,它显示它只有 1 个元素,而它应该有 26 个。

Perl6 REPL 中的以下示例:

> my @a = 'a'..'z'
[a b c d e f g h i j k l m n o p q r s t u v w x y z]
> my @a1 = @a.subst(/<[aeiou]>/, 1, :g)
[1 b c d 1 f g h 1 j k l m n 1 p q r s t 1 v w x y z]
> @a1.elems
1#this should be 26
> @a.elems
26

如何通过整个数组的文本替换来更改数组,并返回一个数组?

另外:perl6 网站已关闭,我无法访问许多手册页 :(

【问题讨论】:

  • 请使用docs.perl6.wakelift.de,直到硬件和/或DNS问题得到解决
  • docs.perl6.org 现在应该重新上线了。如果没有,请清除您的 DNS 缓存。
  • 一些方法假定它们的调用者是复数容器。如果它实际上是单数,他们可能会强制它成为包含该单一事物的复数容器。相反,其他方法假设它们的调用者是一个单一的东西。如果它实际上是复数,他们可能会将其强制为单一事物。 .subst 假设它的调用者是单个字符串。如果它实际上是一个数组,它将数组的元素连接成一个字符串,元素之间有空格。因此,您看到的行为。

标签: raku


【解决方案1】:

通过使用&gt;&gt;. 超级运算符:这将调用列表中每个元素的给定方法,并创建调用结果的列表。

my @a = "a".."z";
my @b = @a>>.subst(/ <[aeiou]> /, 1, :g);
dd @a, @b;

# Array @a = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
# Array @b = ["1", "b", "c", "d", "1", "f", "g", "h", "1", "j", "k", "l", "m", "n", "1", "p", "q", "r", "s", "t", "1", "v", "w", "x", "y", "z"]

【讨论】:

    【解决方案2】:

    .subst 是一个 Str 方法。

    这意味着它假定它的第一个参数(调用者)是一个 Str。如果它还不是 Str,它会被强制转换为 Str

    当您在数组上调用.Str 时,它会将所有值连接在一起,并以空格作为分隔符。

    my @a = < a b c >;
    say @a.perl;       # ["a", "b", "c"]
    say @a.Str.perl;   # "a b c"
    

    所以这三行是完全等价的:

    @a.subst(/<[aeiou]>/, 1, :g);
    @a.Str.subst(/<[aeiou]>/, 1, :g);
    @a.join(" ").subst(/<[aeiou]>/, 1, :g);
    

    Perl6 这样做是因为它是一致的。你总是知道对.subst 的单个调用的输出是单个Str。您还知道调用者被视为 Str

    如果它在数组上做了一些不同的事情,就很难跟踪哪些方法会根据调用者发生变化以及它们是如何变化的。

    我们只需要看看 Perl5 就知道当每个函数的每个怪癖不一致时要记住它们是多么困难。
    (试想一下 Perl5 中默认在 $_ 上运行的所有函数,以及它们在标量与列表上下文中的作用。)


    您不想在单个数组值上调用.subst,而是要在它包含的每个值上调用它。

    有几种方法可以做到这一点:

    my @ = @a.map( *.subst(…) )
    
    my @ = @a».subst(…)
    
    my @ = do for @a { .subst(…) }
    
    my @ = @a.duckmap( -> Str $_ { .subst(…) } ) # only change Str's
    

    【讨论】:

    • 您是否建议分配给匿名数组@,或者使用.= 运算符更新@a,如@a.=map( *.subst(…) );?一个比另一个更受青睐吗?是否存在@a.=map( *.subst(…) ); 表单会失败而@ 匿名数组表单会成功的情况?谢谢!
    • @jubilatious1 我建议默认创建新值,因为这可能会在以后产生问题。想象一下,您有一个将数组作为输入并对其进行适当修改的函数。现在想象一下,您使用一个不想修改的数组调用它。更糟糕的是,您甚至可能需要一段时间才能注意到这种情况,更不用说追踪发生的地点和方式了。 (实际上我建议返回一个 Sequence 并让您的调用者决定是否要在生成值时保留这些值。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 2012-09-14
    • 2019-12-25
    • 2013-11-20
    • 1970-01-01
    相关资源
    最近更新 更多