【问题标题】:Why doesn't my Perl map return anything?为什么我的 Perl 映射不返回任何内容?
【发布时间】:2010-09-05 22:35:33
【问题描述】:

当我运行以下语句时:

@filtered = map {s/ //g} @outdata;

它返回的是一个空列表,而不是我期望的过滤列表。我要做的是从字符串数组(这是一个 XML 文件)中删除每次出现的  

显然,我不明白一些事情。谁能告诉我这样做的正确方法可能是什么,为什么这对我不起作用?

【问题讨论】:

标签: perl map


【解决方案1】:

请注意,map 也会修改您的源数组。所以你可以这样做:

map {s/ //g} @outdata;

并完全跳过@filtered 变量,或者如果您需要保留原件,

@filtered = @outdata;
map {s/ //g} @filtered;

虽然在这种情况下,使用 foreach 可能更具可读性:

s/ //g foreach @filtered;

【讨论】:

  • map 在 void 上下文中通常被认为是糟糕的形式,并且不会超过 for @filtered { ... }
【解决方案2】:

试试这个:

@filtered = map {s/ //g; $_} @outdata;

问题是 perl 中的 s 运算符修改了 $_ 但实际上返回了它所做的更改次数。因此,最后额外的 $_ 导致 perl 返回 @outdata 的每个元素的修改后的字符串。

【讨论】:

【解决方案3】:

Greg 的答案有一个问题,即它会修改原始数组,因为 $_ 是通过别名传递的。你需要:

@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata;

【讨论】:

    【解决方案4】:

    为了跟进 Tithonium 的观点,这也可以解决问题:

    @filtered = map {local $_=$_; s/ //g; $_} @outdata;
    

    “本地”确保您处理的是副本,而不是原件。

    【讨论】:

      【解决方案5】:

      在 perl 5.14 中,您可以将 /r 正则表达式修饰符用于make non-destructive substitution

      @filtered = map {s/ //gr} @outdata;
      

      【讨论】:

        【解决方案6】:
        use Algorithm::Loops "Filter";
        @filtered = Filter { s/ //g } @outdata;
        

        【讨论】:

          【解决方案7】:

          与 Greg 的回答相反,您可能会误用 grep:

          @filtered = grep {s/ //g; 1} @outdata;
          

          不要这样做。

          【讨论】:

            猜你喜欢
            • 2016-11-26
            • 1970-01-01
            • 2010-11-30
            • 2012-04-02
            • 2018-01-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多