要查明项目是否在数组或列表中,我使用智能匹配~~
运算符。但这只适用于简单的数组/列表,以确定是否存在这样的项目。是否有类似的方法将此运算符用于列表列表?列表按第一列排序。由于尺寸非常大,我正在寻找一些最有效,最快的核心解决方案。此外,应返回第二列的值。
列表示例,第一列具有唯一值,已排序:
my $list = [
[ 'alpha' , 'item X' ],
[ 'beta' , 'item Q' ],
[ 'gama' , 'item C' ],
...
];
...搜索'beta'
附带结果'item Q'
,搜索'omega'
附带结果undef
。
答案 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)
~~~
运算符或智能匹配应该在二维数组上运行。
这是我能想到的最有效的方法,看看项目是否在数组之外,然后循环遍历数组。
请参阅我的回复的第一条评论。它似乎是实验性的,建议远离智能匹配。在发表评论帖之前我一直没有意识到。道歉。