【问题标题】:Perl Item in Array数组中的 Perl 项
【发布时间】:2014-06-23 11:17:36
【问题描述】:

我是 Perl 新手,这是找出项目是否存在于数组中的最简单方法

就像在 python 中我可以做到这一点

item = 'apple'
list = ['apple', 'banana']
if item in list:
 print item

output >>> 'apple'

在perl中我可以这样做

my $item = 'appel'
my @array = ('apple', 'banana')
for (@array){
 if ($_ eq $item){ print $item }
}

如果我的数组超过 100 个项目,for 循环将花费太长时间

【问题讨论】:

  • 根据您使用列表内容的其他方式(以及其他一些考虑因素),散列可能是更好的方法。它的搜索将是 O(1),而不是列表的 O(n) 方法。

标签: python arrays perl list


【解决方案1】:

核心List::Util 模块提供了一个方便的别名,用于循环遍历所有元素直到匹配:

#!/usr/bin/perl

use strict;
use warnings;
use List::Util qw(first);

my $item = 'apple';
my @array = ('apple', 'banana');

if (defined first {$_ eq $item} @array) {
    print $item;
}

first 将停止迭代并在找到匹配项后立即返回。不幸的是,如果找不到匹配项,它会返回 undef,因此您无法使用它来查找数组是否包含 undef 值。

如果您有 1.33 或更高版本,您可以使用适用于 undefany 方法:

use List::Util qw(any);
...
if (any {$_ eq $item} @array) {
    print $item;
}

【讨论】:

  • List::Util 的any 是一个更好的主意。 (虽然它需要最新版本的 List::Util。)想象一下my $item = undef(也就是说,我试图找出undef 是否在数组中)。无论@array 是否包含undef,您的if 条件将始终为真!
  • 感谢@tobyink,很高兴看到添加了该方法!更新了答案。
【解决方案2】:

List::MoreUtils 中的any 方法将在任何元素(找到第一个时停止进一步查找)满足条件时返回 true。

use List::MoreUtils 'any';

my $item = 'appel';
my @array = ('apple', 'banana');

print "$item\n" if any { $_ eq $item } @array;

或使用散列切片进行快速查找,

my %look;
@look{@array} = ();
print "$item\n" if exists $look{$item};

【讨论】:

    【解决方案3】:

    请注意,Python 的 in 运算符也循环遍历列表,但在优化的 C 代码中这样做,因此您不会注意到小到中等列表的缓慢性。大型列表的线性搜索花费大量时间,无论使用何种语言。

    最接近in 运算符的内置Perl 函数是内置的grep。如果在数组中找到$item,标量上下文中的grep {$_ eq $item} @array 将返回一个真值。在你的情况下:

    my $item = 'apple';
    my @array = ('apple', 'banana');
    if (grep {$_ eq $item} @array) {
      print $item, "\n";
    }
    

    Python 的in 运算符也可以由dict 等容器定义,以使用比线性搜索更有效的容器特定查找。 in 的这种用法的 Perl 等价物是 exists 函数。

    【讨论】:

      【解决方案4】:

      如果您想查明某个项目是否存在于项目列表中,那么使用数组是错误的数据结构。您应该使用哈希。

      当然,从数组创建散列很简单。

      my %hash = map { $_ => 1 } @array;
      
      # Then checking for existence is simple
      if ($hash{$item}) {
        # do something
      }
      

      【讨论】:

      • 如果您的项目是类似字符串的东西(例如字符串、数字),这当然是最好的方法。否则使用anygrep
      猜你喜欢
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      • 2010-09-05
      • 1970-01-01
      相关资源
      最近更新 更多