Подтвердить что ты не робот

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";
}
4b9b3361

Ответ 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";
}