Perl:if(list中的元素) [英] Perl: if ( element in list )

查看:117
本文介绍了Perl:if(list中的元素)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找列表中某个元素的存在.

I'm looking for presence of an element in a list.

在Python中,有一个in关键字,我会做类似的事情:

In Python there is an in keyword and I would do something like:

if element in list:
    doTask

Perl中是否存在等效功能,而无需手动遍历整个列表?

Is there something equivalent in Perl without having to manually iterate through the entire list?

推荐答案

更新:

smartmatch系列功能现在处于实验阶段

在v5.10.0中添加并在v5.10.1中进行了重大修改的智能匹配一直是人们经常抱怨的问题.尽管有很多方法可以使用它,但对于Perl的用户和实现者来说,它也被证明是有问题和令人困惑的.关于如何最好地解决该问题,已经有许多建议.显然,smartmatch几乎肯定会在未来发生变化或消失.不建议依靠其当前行为.

Smart match, added in v5.10.0 and significantly revised in v5.10.1, has been a regular point of complaint. Although there are a number of ways in which it is useful, it has also proven problematic and confusing for both users and implementors of Perl. There have been a number of proposals on how to best address the problem. It is clear that smartmatch is almost certainly either going to change or go away in the future. Relying on its current behavior is not recommended.

现在将在解析器看到~~,给定或何时发出警告.

Warnings will now be issued when the parser sees ~~, given, or when.




如果您可以不再需要Perl v5.10,则可以使用以下任何示例.

  • 智能匹配~~ 运算符




    If you can get away with requiring Perl v5.10, then you can use any of the following examples.

    • The smart match ~~ operator.

      if( $element ~~ @list ){ ... }
      if( $element ~~ [ 1, 2, 3 ] ){ ... }
      

    • 您还可以使用

    • You could also use the given/when construct. Which uses the smart match functionality internally.

      given( $element ){
         when( @list ){ ... }
      }
      

    • 您还可以将for循环用作"topicalizer"(这意味着它设置了$_).

    • You can also use a for loop as a "topicalizer" ( meaning it sets $_ ).

      for( @elements ){
         when( @list ){ ... }
      }
      

    • 在Perl 5.12中将会出现的一件事是使用when的后缀版本的能力.这使得它甚至更像ifunless.

      One thing that will come out in Perl 5.12 is the ability to use the post-fix version of when. Which makes it even more like if and unless.

      given( $element ){
        ... when @list;
      }
      


      如果您必须能够在旧版本的Perl上运行,那么仍然有几种选择.

      • 您可能会认为您可以使用列表: :Util :: first ,但是有一些边缘条件使它有问题.


        If you have to be able to run on older versions of Perl, there still are several options.

        • You might think you can get away with using List::Util::first, but there are some edge conditions that make it problematic.

          在此示例中,很明显,我们希望成功匹配0.不幸的是,此代码每次都会打印failure.

          In this example it is fairly obvious that we want to successfully match against 0. Unfortunately this code will print failure every time.

          use List::Util qw'first';
          my $element = 0;
          if( first { $element eq $_ } 0..9 ){
            print "success\n";
          } else {
            print "failure\n";
          }
          

          您可以检查 first 的返回值为了获得确定性,但是如果我们实际上希望与undef的匹配成功,那将失败.

          You could check the return value of first for defined-ness, but that will fail if we actually want a match against undef to succeed.

          但是,您可以放心使用 grep .

          You can safely use grep however.

          if( grep { $element eq $_ } 0..9 ){ ... }
          

          这是安全的,因为grep在标量上下文中被调用.在标量上下文中调用时,数组返回元素的数量.因此,即使我们尝试与undef匹配,这也将继续起作用.

          This is safe because grep gets called in a scalar context. Arrays return the number of elements when called in scalar context. So this will continue to work even if we try to match against undef.

          您可以使用封闭的for循环.只要确保调用last,即可在成功匹配时退出循环.否则,您可能最终会多次运行代码.

          You could use an enclosing for loop. Just make sure you call last, to exit out of the loop on a successful match. Otherwise you might end up running your code more than once.

          for( @array ){
            if( $element eq $_ ){
              ...
              last;
            }
          }
          

        • 您可以将for循环放入if语句的条件内...

        • You could put the for loop inside the condition of the if statement ...

          if(
            do{
              my $match = 0;
              for( @list ){
                if( $element eq $_ ){
                  $match = 1;
                  last;
                }
              }
              $match; # the return value of the do block
            }
          ){
            ...
          }
          

        • ...但是将for循环放在if语句之前可能更清楚.

        • ... but it might be more clear to put the for loop before the if statement.

          my $match = 0;
          for( @list ){
            if( $_ eq $element ){
              $match = 1;
              last;
            }
          }
          
          if( $match ){ ... }
          

        • 如果只匹配字符串,则还可以使用哈希.如果@list很大,可以提高程序速度,您将与%hash多次匹配.尤其是如果@array不变,因为这样一来,您只需加载一次%hash.

        • If you're only matching against strings, you could also use a hash. This can speed up your program if @list is large and, you are going to match against %hash several times. Especially if @array doesn't change, because then you only have to load up %hash once.

          my %hash = map { $_, 1 } @array;
          if( $hash{ $element } ){ ... }
          

        • 您还可以创建自己的子例程.这是使用原型的有用情况之一.

        • You could also make your own subroutine. This is one of the cases where it is useful to use prototypes.

          sub in(&@){
            local $_;
            my $code = shift;
            for( @_ ){ # sets $_
              if( $code->() ){
                return 1;
              }
            }
            return 0;
          }
          
          if( in { $element eq $_ } @list ){ ... }
          

        • 这篇关于Perl:if(list中的元素)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆