Perl: 配列の中に、特定の要素が含まれるかを確かめるには?

Perl: 配列の中に、特定の要素が含まれるかを確かめるには?

「配列の中に、〇〇が含まれていたら〜」という条件分岐を書きたい時があります。
その場合、Perlではどのように書くのがスマートなのでしょうか。

grep を使う

grep を使うと、スマートに書くことができます。
例として、フルーツの名前の配列に、banana が含まれるかという条件を書いて見ましょう。

my @fruits = ('apple', 'banana', 'orange');
if (grep { $_ eq 'banana' } @fruits) {
print 'banana is included !';
}

数行で実現することができました。

とはいえ、上の例は少し分かりづらいです。そもそも、grep は、ブレース(波括弧)の中に、条件式を書き、返ってくる値は、スカラで受け取る時は「条件を満たした要素の数」が返ってきます。そのため、以下のように、$count などの関数名でいったん受け取った方が、分かりやすいコードだと思います。

my @fruits = ('apple', 'banana', 'orange');
my $count = grep { $_ eq 'banana' } @fruits;
if ($count >= 1) {
print 'banana is included !';
}

for を使う

もちろん、for を使っても書くことができます。その場合は、以下のように書くことができます。

my @fruits = ('apple', 'banana', 'orange');
my $is_banana_included = 0;
for my $fruit (@fruits) {
if ($fruit eq 'banana') {
$is_banana_included = 1;
next;
}
}
if ($is_banana_included) {
print 'banana is included !';
}

まず、$is_banana_included のような、「含まれていたかどうか」というフラグを用意しておき、その後はfor でループしつつ、条件に一致したら、フラグに1を設定し、next でループを抜けます(それ以降のループは、意味がないため)。

まとめ

どちらを使うかは、好みによるかと思いますが、grep を使った方が、コードの行数は減らすことができます。ただし、for を使った方が、分かりやすいような気がしています。後から条件を増やしていく場合などは、for の方が向いているかと思います。