Сокращение для изменения значения в массиве хэш-ссылок

У меня есть массив хэш-рефов. Поле даты в хеше хранится в эпохе. Я должен отформатировать его для чтения человеком, прежде чем возвращать массив. Ниже приведен мой код:

for my $post (@sorted) {
        $post->{date} = format_time($post->{date});
        push @formatted, $post;
}

я пытался

my @formatted =  map {$_{date} = format_time($_{date})} @sorted;

Все поля, кроме {date}, удаляются.

Есть ли более разумный метод?

Спасибо


person Weiyan    schedule 25.03.2011    source источник
comment
Что не так с тем, как вы делаете это в первую очередь?   -  person Brian Roach    schedule 25.03.2011


Ответы (5)


$_->{date} = format_time($_->{date}) for @sorted.

Тогда даты в @sorted будут преобразованы.

person tadmc    schedule 25.03.2011

Нет ничего плохого в цикле for, который вы сейчас используете. Карта тоже может работать, но есть две проблемы:

  • Хеш-ссылка в массиве хранится в скаляре $_. Вы обращаетесь к хешу %_.
  • Возвращаемое значение блока — это то, что окажется в результирующем массиве. В вашем случае это результат присваивания, а не весь хешреф.

Также обратите внимание, что хэш-ссылки в @sorted будут изменены. Следующий оператор карты должен работать для вас:

my @formatted = map { $_->{date} = format_time($_->{date}); $_ } @sorted;
person Anomie    schedule 25.03.2011

Если вы действительно хотите:

sub format_time_in_place {
    my $time = $_[0];
    # do work
    $_[0] = $reformatted_time;
}

# elsewhere
format_time_in_place($_->{date}) for @sorted;

Я любезно переименовал эту функцию, чтобы снизить вероятность того, что у программиста, обслуживающего обслуживание, возникнет искушение стать смертоносным убийцей с топором. Все еще может быть элемент шока, если указанный программист не знал, что вы можете изменить переданные в аргументах правильные манипуляции с @_.

person btilly    schedule 25.03.2011

Это эквивалентно вашему коду:

$_->{date} = format_time($_->{date}) for @sorted;
@formatted = @sorted;

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

person ikegami    schedule 25.03.2011

Если вы хотите или не возражаете не ссылаться на те же хэши, что и в @sorted, вы можете:

my @formatted = map +{ %$_, 'date' => format_time($_->{date}) }, @sorted;
person ysth    schedule 25.03.2011