2008-10-27 1 views

ответ

21

заимствованы из here

%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"} 
9

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

my %number_for = (
    jan => 1, 
    feb => 2, 
#etc... 
); 
#... 
do_something_with($number_for{$month}) 
2
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) 
); 

Или с помощью a zip function:

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

Это намного сложнее, чем это должно быть. – 2008-10-28 06:03:02

+0

Слишком умно, и, как сказал Брэд, это усложнило, чем нужно. Хорошо показать, что TMTOWTDI, но эти способы излишне запутаны, ИМО. – 2008-10-28 13:03:05

10

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

my %month; @month{qw/jan feb mar apr may jun 
        jul aug sep oct nov dec/} = (1 .. 12); 
0

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

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. Или вы можете найти модуль даты/времени, более подходящий для ваших нужд; это выходит за рамки этого вопроса.

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

0

Определенно хэш, как это было предложено другими.

2

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

# 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

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

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

$month_number = $mon_2_num{lc($month_name_abbrev)}; 
2

Другой способ сделать это, используя хэш-фрагмент:

@month{qw(jan feb mar apr may jun jul aug sep oct nov dec)} = 1..12;