Grep, чтобы найти элемент в массиве Perl
Каждый раз, когда я ввожу что-то, код всегда говорит мне, что он существует. Но я знаю, что некоторые из входов не существуют. Что не так?
#!/usr/bin/perl
@array = <>;
print "Enter the word you what to match\n";
chomp($match = <STDIN>);
if (grep($match, @array)) {
print "found it\n";
}
Ответы
Ответ 1
Первый аргумент, который вы даете grep, должен оцениваться как true или false, чтобы указать, было ли совпадение. Поэтому это должно быть:
# note that grep returns a list, so $matched needs to be in brackets to get the
# actual value, otherwise $matched will just contain the number of matches
if (my ($matched) = grep $_ eq $match, @array) {
print "found it: $matched\n";
}
Если вам нужно сопоставлять множество разных значений, вам также стоит подумать о том, чтобы поместить данные array
в hash
, так как хэши позволяют вам делать это эффективно, не выполняя итерацию через список.
# convert array to a hash with the array elements as the hash keys and the values are simply 1
my %hash = map {$_ => 1} @array;
# check if the hash contains $match
if (defined $hash{$match}) {
print "found it\n";
}
Ответ 2
Кажется, вы используете grep()
как утилиту Unix grep
, что неверно.
Perl grep()
в скалярном контексте оценивает выражение для каждого элемента списка и возвращает количество раз, когда выражение было истинным.
Поэтому, когда $match
содержит любое "истинное" значение, grep($match, @array)
в скалярном контексте всегда возвращает число элементов в @array
.
Вместо этого попробуйте использовать оператор сопоставления шаблонов:
if (grep /$match/, @array) {
print "found it\n";
}
Ответ 3
Это можно сделать, используя List:: Util first
function:
use List::Util qw/first/;
my @array = qw/foo bar baz/;
print first { $_ eq 'bar' } @array;
Другие функции из List::Util
, такие как max
, min
, sum
также могут быть полезны для вас
Ответ 4
В дополнение к тому, что опубликовано в eugene и stevenl, вы можете столкнуться с проблемами с использованием как <>
, так и <STDIN>
в одном script: <>
итерации посредством (= конкатенации) всех файлов, заданных в качестве аргументов командной строки.
Однако, если пользователь когда-либо забудет указать файл в командной строке, он будет читать из STDIN, и ваш код будет ждать всегда на входе
Ответ 5
Я мог бы предположить, что если ваш массив содержит строку "hello", и если вы ищете "he", grep возвращает true, хотя "he" может не быть элементом массива.
Может быть,
if (grep(/^$match$/, @array))
больше.
Ответ 6
Вы также можете проверить одно значение в нескольких массивах, например,
if (grep /$match/, @array, @array_one, @array_two, @array_Three)
{
print "found it\n";
}