Вот ссылка на сайт, в котором говорится, как вы можете читать один символ в 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()
Perl создал в grep (), функция разработана, чтобы сделать это.
@matches = grep( /^MyItem$/, @someArray );
или можно вставить любое выражение в matcher
@matches = grep( $_ == $val, @a );
Если у Вас есть жемчуг 5.10, используйте оператор умного соответствия ~~
print "Exist\n" if $var ~~ @array;
Это почти волшебно.
Интересное решение, специально для повторного поиска:
my %hash;
map { $hash{$_}++ } @a;
print $hash{$val};
Используйте первую функцию из Списка:: Util, который стал стандартом с Perl....
use List::Util qw/first/;
my @a = qw(foo bar baz);
if ( first { $_ eq 'bar' } @a ) { say "Found bar!" }
NB. сначала возвращает первый элемент, который он находит и так не должен выполнять итерации через полный список (который является тем, что grep сделает).
Один возможный подход должен использовать Список:: MoreUtils 'любая' функция.
use List::MoreUtils qw/any/;
my @array = qw(foo bar baz);
print "Exist\n" if any {($_ eq "foo")} @array;
Обновление: исправленный на основе комментария zoul.
Этому отвечают в ответе 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;
$ perl -e '@a = qw(foo bar baz);$val="bar";
if (grep{$_ eq $val} @a) {
print "found"
} else {
print "not found"
}'
найденный
$val='baq';
не найденный
Если Вам не нравится ненужная зависимость, реализация any
или first
самостоятельно
sub first (&@) {
my $code = shift;
$code->() and return $_ foreach @_;
undef
}
sub any (&@) {
my $code = shift;
$code->() and return 1 foreach @_;
undef
}