【问题标题】:How do I remove unwanted values from the beginning of an array in Perl?如何从 Perl 数组的开头删除不需要的值?
【发布时间】:2009-07-10 17:12:34
【问题描述】:

我使用push 函数将值存储在一个数组中。数组中的第一个值存储在第四个元素而不是第一个元素。

例如,当我打印第一个元素$array[1] 存储值后,它会打印空格/空,但是当我打印第四个元素$array[4] 时,它会打印第一个值。如何删除数组开头不需要的值?

【问题讨论】:

  • 您在阵列中推什么?这可能是问题所在。听起来您正在将一个数组推入另一个数组,而不是推一个标量。顺便说一句,第一个元素的索引是 0,而不是 1。
  • @jeje:我在匹配正则表达式后推入值。像这样的东西: push (@value, join("",$file=~ /$find/))
  • @shubster 好的,所以你在数组@value 中推送一个数组(显然是 5 个元素)。
  • 您可能在您的正则表达式中使用了捕获,而您实际上并不想要捕获。
  • array indexes/indices are zero-based时,第四个元素不是$array[4]

标签: perl arrays


【解决方案1】:

您可以使用“shift”运算符从数组的前面删除元素。

但我认为问题比这更深,而且你的看法是错误的。如果您在数组中存储未知的“不需要的”值,您需要找出发生这种情况的位置和原因并加以预防,而不仅仅是绕过这些值来查找您要查找的内容。

【讨论】:

    【解决方案2】:
    while ( value_meets_shubster_s_definition_of_crap($array[0]) ) {
      shift @array;
    }
    
    sub value_meets_shubster_s_definition_of_crap {
      my $value = shift;
      &helip;
      return true or false;
    }
    

    ...但最好避免将“垃圾”值放在数组中。

    【讨论】:

    • "最好避免将“废话”值放在数组中。" - 谢谢你,我忘记了一条黄金法则。
    【解决方案3】:

    你是如何创建数组的?使用我惊人的 ESP 能力,我猜你有一个 split 在某处保持领先的空白字段。如果我错了,你必须告诉我们更多关于你在做什么。

    您在这里遇到了一点XY 问题。您是在问我们如何实施您已经选择的解决方案,而不是让我们实际解决问题。

    【讨论】:

      【解决方案4】:

      如果你想消除所有不需要的值:

      @array = grep { not value_meets_shubster_s_definition_of_crap($_) } @array;
      

      但是,正如 David Dorward 所指出的,这也消除了数组中间不需要的值。要仅删除开头的值,您可以使用 List::MoreUtils 中的 first_index,这可能比 shifts 的循环更有效:

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      use List::MoreUtils qw( first_index );
      
      my @array = ( 0, 1, 0, 2 );
      my $begin = first_index { not is_unwanted($_) } @array;
      
      @array = @array[ $begin .. $#array ];
      
      print "@array\n";
      
      sub is_unwanted {
          my ($v) = @_;
          return if $v;
          return 1;
      }
      
      __END__
      

      输出:

      C:Temp> yjk
      1 0 2
      

      更新:我的预感似乎错了:

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      use Benchmark qw( cmpthese );
      use List::MoreUtils qw( first_index );
      
      my @array = ( 0, 1, 0, 2, 3, 4, 5, 6, 7, 8, 9 );
      
      cmpthese -10, {
          'first_index' => \&using_first_index,
          'shift'       => \&using_shift,
          'nop'         => \&nop,
      };
      
      sub using_first_index {
          my @result = @array;
          my $begin = first_index { not is_unwanted($_) } @result;
          @result = @result[ $begin .. $#result ];
      }
      
      sub using_shift {
          my @result = @array;
          shift @result while is_unwanted($result[0]);
      }
      
      sub nop { my @result = @array; }
      
      sub is_unwanted {
          my ($v) = @_;
          return if $v;
          return 1;
      }
      

      结果:

                      Rate first_index       shift         nop
      first_index  75767/s          --        -71%        -89%
      shift       258810/s        242%          --        -61%
      nop         664021/s        776%        157%          --
      

      【讨论】:

      • 这会让数组中间的“废话”值通过。问题确实指定了开头:)
      • @David Dorward: ITYM 消除
      猜你喜欢
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多