How do pass one array and one string as arguments to a function?

前端 未结 5 1286
感情败类
感情败类 2021-01-13 14:44

Because I can\'t find a convenient way to check if $str is in @array, I\'m trying to make one myself, but it is not working.

I guess it is

相关标签:
5条回答
  • 2021-01-13 15:11

    You can't pass arrays to subs, only lists of scalars.

    ifin(@f, $k);
    

    is the same as

    ifin($f[0], $f[1], $f[2], $f[3], $k);
    

    because @f evaluates to a list of its elements.

    One way of passing an array to a sub is to pass a reference.

    sub ifin {
       my ($array, $str) = @_;
       for my $e (@$array) {
          return 1 if $e eq $str;
       }
    
       return 0;
    }
    
    my @f = (1,2,3,4);
    my $k = 1;
    print(ifin(\@f, $k), "\n");
    

    By the way, that can also be written as:

    my @f = (1,2,3,4);
    my $k = 1;
    print(( grep { $_ eq $k } @f ) ? 1 : 0, "\n");
    

    You could keep the existing calling convention by using pop.

    sub ifin {
       my $str = pop(@_);
       for my $e (@_) {
          return 1 if $e eq $str;
       }
    
       return 0;
    }
    
    my @f = (1,2,3,4);
    my $k = 1;
    print(ifin(@f, $k), "\n");
    
    0 讨论(0)
  • 2021-01-13 15:14

    How about $str ~~ @arr in a smartmatch? That's available in Perl 5.10.

    use 5.010;
    use strict;
    use warnings;
    
    my $str = 'three';
    my @arr = qw(zero one two three four);
    my @badarr = qw(zero one two four eight);
    
    say '$str ', $str ~~ @arr? 'is' : 'is not', ' in $arr.';
    say '$str ', $str ~~ @badarr? 'is' : 'is not', ' in $badarr.';
    

    Output, as expected:

    $str is in $arr.
    $str is not in $badarr.
    
    0 讨论(0)
  • 2021-01-13 15:22

    You could use a prototype, but those are kind of brittle. I would pass in a reference to @f as the first argument, like this:

    use 5.010;
    use strict;
    use warnings;
    
    sub ifin
    {
    my ($array,$str)=@_;
     for my $i (@$array)
     {
      if ($i eq $str)
      {
       return True
      }
     }
     return False
    }
    
    
    my @f= (1,2,3,4);
    my $k=1;
    print ifin(\@f,$k);
    

    For a long list, you avoid making a copy of every list element as well.

    0 讨论(0)
  • 2021-01-13 15:24

    You could pass your arguments in reverse order (print ifin($k, @f);), so array is going last. When you catch them now from subroutine, string comes first and array gets populated with any list items after it.

    0 讨论(0)
  • 2021-01-13 15:27

    You may want to check any in the List::MoreUtils package, you just use it like:

    use List::MoreUtils 'any';
    
    my @f= qw(1 2 3 4);
    my $k=10;
    
    print "yes\n" if( any { $_ == $k } @f );
    

    check the documentation in:

    perldoc List::MoreUtils.
    
    0 讨论(0)
提交回复
热议问题