Как я могу проверить, что значение присутствует в массиве (списке) в Perl?

Вот ссылка на сайт, в котором говорится, как вы можете читать один символ в Windows, Linux и OSX: http://code.activestate.com/recipes/134892/

class _Getch:
    """Gets a single character from standard input.  Does not echo to the
screen."""
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()

    def __call__(self): return self.impl()


class _GetchUnix:
    def __init__(self):
        import tty, sys

    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch


class _GetchWindows:
    def __init__(self):
        import msvcrt

    def __call__(self):
        import msvcrt
        return msvcrt.getch()


getch = _Getch()

20
задан Community 23 May 2017 в 12:09
поделиться

8 ответов

Perl создал в grep (), функция разработана, чтобы сделать это.

@matches = grep( /^MyItem$/, @someArray ); 

или можно вставить любое выражение в matcher

@matches = grep( $_ == $val, @a ); 
20
ответ дан 29 November 2019 в 22:25
поделиться

Если у Вас есть жемчуг 5.10, используйте оператор умного соответствия ~~

print "Exist\n" if $var ~~ @array;

Это почти волшебно.

38
ответ дан 29 November 2019 в 22:25
поделиться

Интересное решение, специально для повторного поиска:

my %hash;
map { $hash{$_}++ } @a;
print $hash{$val};
5
ответ дан 29 November 2019 в 22:25
поделиться

Используйте первую функцию из Списка:: Util, который стал стандартом с Perl....

use List::Util qw/first/;

my @a = qw(foo bar baz);
if ( first { $_ eq 'bar' } @a ) { say "Found bar!" }

NB. сначала возвращает первый элемент, который он находит и так не должен выполнять итерации через полный список (который является тем, что grep сделает).

15
ответ дан 29 November 2019 в 22:25
поделиться

Один возможный подход должен использовать Список:: MoreUtils 'любая' функция.

use List::MoreUtils qw/any/;

my @array = qw(foo bar baz);

print "Exist\n" if any {($_ eq "foo")} @array;

Обновление: исправленный на основе комментария zoul.

8
ответ дан 29 November 2019 в 22:25
поделиться

Этому отвечают в ответе perlfaq4 на, "Как я могу сказать, содержится ли определенный элемент в списке или массиве?".

Для поиска perlfaq Вы могли перерыть список всех вопросов в perlfaq использование Вашего любимого браузера.

Из командной строки можно использовать переключатель-q для perldoc для поиска ключевых слов. Вы нашли бы свой ответ путем поиска "списка":

perldoc -q list

(части этого ответа внесены Anno Siegel и brian d foy),

Слушание слова "в" является признаком, что, вероятно, необходимо было использовать хеш, не список или массив, чтобы хранить данные. Хеши разработаны для ответа на этот вопрос быстро и эффективно. Массивы не.

Однако существует несколько способов приблизиться к этому. В Perl 5.10 и позже, можно использовать умный оператор соответствия, чтобы проверить, что объект содержится в массиве или хеше:

use 5.010;

if( $item ~~ @array )
    {
    say "The array contains $item"
    }

if( $item ~~ %hash )
    {
    say "The hash contains $item"
    }

С более ранними версиями Perl необходимо сделать немного больше работы. Если Вы собираетесь сделать этот запрос много раз по значениям произвольной строки, самый быстрый путь состоит в том, чтобы, вероятно, инвертировать исходный массив и поддержать хеш, ключи которого являются значениями первого массива:

@blues = qw/azure cerulean teal turquoise lapis-lazuli/;
%is_blue = ();
for (@blues) { $is_blue{$_} = 1 }

Теперь можно проверить ли $is_blue {$some_color}. Это, возможно, была хорошая идея сохранить блюз всеми в хеше во-первых.

Если значения являются всеми маленькими целыми числами, Вы могли бы использовать простой индексный массив. Этот вид массива займет меньше места:

@primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
@is_tiny_prime = ();
for (@primes) { $is_tiny_prime[$_] = 1 }
# or simply  @istiny_prime[@primes] = (1) x @primes;

Теперь Вы проверяете ли $is_tiny_prime [$some_number].

Если рассматриваемые значения являются целыми числами вместо строк, можно оставить довольно много свободного места при помощи строк битов вместо этого:

@articles = ( 1..10, 150..2000, 2017 );
undef $read;
for (@articles) { vec($read,$_,1) = 1 }

Теперь проверьте, верен ли vec ($read, $n, 1) за некоторый $n.

Эти методы гарантируют быстрые отдельные тесты, но требуют перестройки исходного списка или массива. Они только окупаются, если необходимо протестировать несколько значений против того же массива.

Если Вы тестируете только однажды, стандартный список модулей:: Util экспортирует функцию сначала с этой целью. Это работает путем остановки, после того как это находит элемент. Это записано в C для скорости и ее Perl эквивалентные взгляды как эта подпрограмма:

sub first (&@) {
    my $code = shift;
    foreach (@_) {
        return $_ if &{$code}();
    }
    undef;
}

Если скорость вызывает мало беспокойства, общая идиома использует grep в скалярном контексте (который возвращает количество объектов, которые передали его условие) пересекать весь список. Это действительно обладает преимуществом сообщения Вам, сколько соответствий оно нашло, все же.

my $is_there = grep $_ eq $whatever, @array;

Если Вы хотите на самом деле извлечь элементы соответствия, просто используйте grep в контексте списка.

my @matches = grep $_ eq $whatever, @array;
18
ответ дан 29 November 2019 в 22:25
поделиться
$ perl -e '@a = qw(foo bar baz);$val="bar";
if (grep{$_ eq $val} @a) {
  print "found"
} else {
  print "not found"
}'

найденный

$val='baq';

не найденный

2
ответ дан 29 November 2019 в 22:25
поделиться

Если Вам не нравится ненужная зависимость, реализация any или first самостоятельно

sub first (&@) {
  my $code = shift;
  $code->() and return $_ foreach @_;
  undef
}

sub any (&@) {
  my $code = shift;
  $code->() and return 1 foreach @_;
  undef
}
1
ответ дан 29 November 2019 в 22:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: