Какой самый простой или эффективный способ преобразовать аббревиатуру месяца в число в Perl? (т. е. "Ян" на 1) - PullRequest
7 голосов
/ 28 октября 2008

Если я импортирую библиотеку для использования метода, это будет стоить того? Занимает ли импорт много памяти?

Ответы [ 9 ]

21 голосов
/ 28 октября 2008

заимствовано из здесь

%mon2num = qw(
    jan 1  feb 2  mar 3  apr 4  may 5  jun 6
    jul 7  aug 8  sep 9  oct 10 nov 11 dec 12
);

и для извлечения

$mon2num{"jan"}
10 голосов
/ 28 октября 2008

Вот еще один способ сделать это:

my %month; @month{qw/jan feb mar apr may jun
                     jul aug sep oct nov dec/} = (1 .. 12);
9 голосов
/ 28 октября 2008

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

my %number_for = (
    jan => 1,
    feb => 2,
#etc...
);
#...
do_something_with($number_for{$month})
2 голосов
/ 30 октября 2008

Еще один способ сделать это с помощью фрагмента хеша:

@month{qw(jan feb mar apr may jun jul aug sep oct nov dec)} = 1..12;
2 голосов
/ 29 октября 2008

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

%mon_2_num = (jan => 1,
              feb => 2,
              ...);

$month_number = $mon_2_num{lc($month_name_abbrev)};
2 голосов
/ 28 октября 2008

Хм - кажется, есть много слишком сложных способов сделать это. Для чего-то эта простая ясность является ключевой:

# create a lookup table of month abbreviations to month numbers
my %month_abbr_to_number_lkup = (
    jan => 1,
    feb => 2,
    mar => 3,
    apr => 4,
    may => 5,
    jun => 6,
    jul => 7,
    aug => 8,
    sep => 9,
    oct => 10,
    nov => 11,
    dec => 12,
);

# get the number for a month
my $number = $month_abbr_to_number_lkup{$abbr}
    || die "Could not convert month abbreviation '$abbr' to a number.";
2 голосов
/ 28 октября 2008
my %month_num = do { my $i = 1; map {; $_ => $i++ } (
    qw( jan feb mar apr may jun jul aug sep oct nov dec )
) };

Или, может быть:

my %month_num;
$month_num{ $_ } = 1 + keys %month_num for (
    qw( jan feb mar apr may jun jul aug sep oct nov dec )
);

Или используя функцию zip :

my %month_num = do {
    my @month = qw( jan feb mar apr may jun jul aug sep oct nov dec );
    zip2( 1 .. 1+$#month, @month );
};
0 голосов
/ 28 октября 2008

Определенно хэш, как предлагают другие.

0 голосов
/ 28 октября 2008

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

my @months = qw(Jan Feb Mar Apr May Jun
                Jul Aug Sep Oct Nov Dec);
my %monthnum = map { $_ => $months[ $_ - 1 ] } 1..12;

(Я предпочитаю этот подход, потому что он сравнительно очевиден: у вас есть список месяцев, затем вы отображаете их с 1..12 (числа, которые имеют смысл для человека) на 0..11 ( числа, которые имеют смысл для компьютера.) Узкие места производительности в вашем коде не будут присутствовать в таком коде, они будут в коде доступа к сети, базе данных или диске, поэтому сконцентрируйтесь на том, чтобы сделать ваш код читабельным. )

Когда вы начнете добавлять к своему коду, вы можете обнаружить, что многие из этих вещей уже сделаны существующими модулями, и, возможно, было бы легче сделать некоторые простые вещи, например, с помощью. Date :: Calc. Или вы можете найти модуль даты / времени, более подходящий для ваших нужд; это выходит за рамки этого вопроса.

Имейте также в виду, что некоторые модули используют авторазделение, когда загружаются только те части модуля, которые необходимы. Кроме того, основное влияние на производительность при использовании большого модуля - это не обязательно ОЗУ, скорее всего, это будет нагрузка на время / ЦП при его загрузке и компиляции до того, как какой-либо код выполнится.

...