使用Perl搜索列表列表中的项目

时间:2013-12-03 22:02:21

标签: perl

要查明项目是否在数组或列表中,我使用智能匹配~~运算符。但这只适用于简单的数组/列表,以确定是否存在这样的项目。是否有类似的方法将此运算符用于列表列表?列表按第一列排序。由于尺寸非常大,我正在寻找一些最有效,最快的核心解决方案。此外,应返回第二列的值。


列表示例,第一列具有唯一值,已排序:

my $list = [
             [ 'alpha' , 'item X' ],
             [ 'beta'  , 'item Q' ],
             [ 'gama'  , 'item C' ],
             ...
           ];

...搜索'beta'附带结果'item Q',搜索'omega'附带结果undef

4 个答案:

答案 0 :(得分:2)

使用以下结构/数据:

my $list = [
              [ "alpha" , "X" ],
              [ "beta"  , "Q" ],
              [ "gama"  , "Z" ],
              [ "delta" , "C" ],
           ];

my $str = "gama";

我发现以下解决方案非常快:

my ($min, $max, $pos, $cmp) = (-1, $#{$list} + 1, undef, -1);
while (($cmp != 0) && (($max - $min) > 1)) {
  $cmp = $str cmp ${$list}[$pos = int(($min + $max) / 2)][0];
  ($min, $max) = ($cmp > 0) ? ($pos, $max) : ($min, $pos);
}

return ($cmp == 0) ? ${$list}[$pos][1] : undef;

答案 1 :(得分:1)

此代码有效......

my @array = (
         [ 'alpha' , 'item 1' ],
         [ 'beta'  , 'item 2' ],
         [ 'alpha' , 'item 3' ],
        );
say 'beta' ~~ @array ? "yep" : "nope"; #=> yep

...因为smartmatch递归:SCALAR ~~ ARRAY智能匹配数组的每个条目,直到一个成功。碰巧,外部数组的元素本身就是数组,所以再次发生同样的事情。

当然,你不应该使用smartmatch。 use List::MoreUtils qw< any >代替:

use List::MoreUtils qw< any >;

my @array = (
         [ 'alpha' , 'item 1' ],
         [ 'beta'  , 'item 2' ],
         [ 'alpha' , 'item 3' ],
        );

if (any { any { 'beta' eq $_ } @$_ } @array) {
  say "yep";
}
else {
  say "nope";
}
#=> yep

这相当丑陋,但any应该比grep更高效(你可以在这里等效使用)。与smartmatch不同,这些解决方案不会做出类似于递归或执行coderefs的偷偷摸摸的意外事情.-


如果你想获得“其他”条目:

use List::MoreUtils qw< any firstval >;

my @array = (
         [ 'alpha' , 'item 1' ],
         [ 'beta'  , 'item 2' ],
         [ 'alpha' , 'item 3' ],
        );
if (my $array = firstval { any { 'beta' eq $_ } @$_ } @array) {
  my $other_item = firstval { 'beta' ne $_ } @$array;
  say "yep: $other_item";
}
else {
  say 'nope';
}
#=> yep: item 2

答案 2 :(得分:1)

如果为多个查询修复$list,则构建键值的映射:

# do this only when $list changes
my %listvalues= map { $_->[0], $_ } @$list ;

...

sub lookup
{
  my ($key)= @_ ;
  return (exists $listvalue{$key} ) ? $listvalues{$key}[1] : undef ;
}

答案 3 :(得分:0)

~~~运算符或智能匹配应该在二维数组上运行。

这是我能想到的最有效的方法,看看项目是否在数组之外,然后循环遍历数组。

编辑:

请参阅我的回复的第一条评论。它似乎是实验性的,建议远离智能匹配。在发表评论帖之前我一直没有意识到。道歉。