Найти элемент в константном массиве Perl - PullRequest
1 голос
/ 07 июля 2019

Hi Stack overfloweans,

Я нахожу значение в массиве, которое является константой allow_value. Если main_value равно одному из значений в массиве allow_value, я печатаю сообщение «Разрешено допустимое значение». Итак, я сделал следующий фрагмент кода.

use constant allowed_value => qw(value1 value2);

my $main_value = 'value2';

my @attr = (allowed_value);

print "Allowed value is correct" if grep $_ eq $main_value, @attr; 

Есть ли способ улучшить код и упростить его? Пожалуйста помоги. Заранее спасибо

1 Ответ

4 голосов
/ 07 июля 2019

grep подходит для небольших наборов, но каждый раз приходится искать весь набор.

Для больших наборов вы можете сделать это немного быстрее, используя List :: Util's any ()функция .Это имеет преимущество перед grep в том, что оно прекращает поиск, когда совпадает один раз.Предполагая случайные данные, в среднем вы будете искать половину списка.

use strict;
use warnings;
use v5.10;
use List::Util 'any';

use constant allowed_values => qw(value1 value2);
my $main_value = 'value3';

say "Good" if any { $_ eq $main_value } allowed_values;

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

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

use strict;
use warnings;
use v5.10;

use constant allowed_values => {
    value1 => 1,  # any true value will do
    value2 => 1,
};
my $main_value = 'value2';

say "Good" if allowed_values->{$main_value};

И если ваш список разрешенных значений длинный, вы можете сгенерировать хеш изсписок, избегающий набора текста.

use constant allowed_values => {
    map { $_ => 1 }
    qw(value1 value2)
};

Недостатком является то, что «постоянные» ссылки на самом деле не являются постоянными.Только ссылка является константой, содержимое этой ссылки может быть изменено.

allowed_values->{foo} = 42;  # this is "fine"

Если это проблема, используйте вместо нее Const :: Fast .

use strict;
use warnings;
use v5.10;

use Const::Fast qw(const);
const my %allowed_values => (
    map { $_ => 1 }
    qw(value1 value2)
);
my $main_value = 'value2';

say "Good" if $allowed_values{$main_value};

Если вы действительно не нуждаетесь в встроенной константе, и обычно вы этого не делаете.

...