用惯用的 Perl 模拟 PHP 的 array_keys 函数

Luc*_*cky 1 php arrays perl

在 PHP 中,有一个函数array_keys,当给定一个可选值时,它将返回与提供的值匹配的数组的所有索引。所以给出这个 PHP 代码:

$array = array("blue", "red", "green", "blue", "blue");
print_r(array_keys($array, "blue"));
Run Code Online (Sandbox Code Playgroud)

它会输出这个:

Array
(
    [0] => 0
    [1] => 3
    [2] => 4
)
Run Code Online (Sandbox Code Playgroud)

除了下面的代码之外,还有更多的 Perlish 方式来完成相同的功能吗?我似乎为此想起了一个mapgrep技巧。

my @a = ("blue", "red", "green", "blue", "blue");

for ($i = 0; $i <= $#a; $i++) {
  push(@b, $i) if ( $a[$i] eq "blue");
}

print join(',', @b)
Run Code Online (Sandbox Code Playgroud)

Sha*_*awn 6

来自handy包的索引函数List::MoreUtils是这样做的:

#!/usr/bin/env perl
use warnings;
use strict;
use Data::Dumper;
use List::MoreUtils qw/indexes/;

my @a = ("blue", "red", "green", "blue", "blue");
my @i = indexes { $_ eq "blue" } @a;
print Dumper(\@i);
Run Code Online (Sandbox Code Playgroud)


Fra*_*tus 5

您的代码不会提供所有三个匹配项,因为您需要将小于或等于运算符与 $#a 一起使用。$#a 是最后一个元素的索引,因此您需要包含它。或者您可以使用 $i < @a ,如本例所示。在标量上下文中,@a 返回比最后一个索引大 1 的元素数。

my @a = ("blue", "red", "green", "blue", "blue");
my @b;
for (my $i = 0; $i < @a; $i++) {
  push(@b, $i) if ( $a[$i] eq "blue");
}

print join(',', @b)
Run Code Online (Sandbox Code Playgroud)

使用 grep 执行此操作的方法是传入一系列数字并使用每个数字索引到您的数组中并进行比较。然后 grep 会将索引返回到您的匹配数组。这是一个例子。

use warnings;
use strict;

my @arr = ("blue", "red", "green", "blue", "blue");

my @matches = grep { $arr[$_] eq "blue" } 0 .. $#arr;

print join(',', @matches)
Run Code Online (Sandbox Code Playgroud)

我发现了一个有类似问题的旧 stackoverflow 线程。