Использование карты или grep в Perl
Я пишу perl-код полный рабочий день в течение пары месяцев (биоинформатика), и я всегда стараюсь улучшить свои навыки. Только сегодня мне стало ясно, что я никогда не использую карту или grep. Оглядываясь назад на мой код, я понимаю, что эти инструменты могли бы сэкономить мне пару строк здесь или там, но только за счет гибкости цикла foreach. Мой вопрос следующий:
Существуют ли какие-либо обстоятельства, с которыми вы столкнулись, когда использование карты или grep принесло значительное преимущество перед циклом foreach/for, помимо сохранения строки или двух из кода?
Спасибо за ваше время!
Ответы
Ответ 1
Schwartzian Transform будет примером:
@sorted = map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [$_, foo($_)] }
@unsorted;
Вы можете сделать это с помощью кучи контуров foreach
, но вам придется выбирать их отдельно, чтобы выяснить, что происходит; как только вы увидите Шварццианское Преобразование, вы сразу узнаете идиому.
В целом я думаю, что map
и grep
хороши тем, что они позволяют четко и компактно представлять ваши намерения без слоев синтаксиса. Если вы видите map
, тогда вы знаете, что происходит какое-то простое преобразование структуры данных; если вы видите grep
, тогда вы знаете, что происходит некоторая фильтрация/выбор. Вы можете сделать все это с помощью foreach
, но цель вашего кода не такая ясная, как это было бы с map
или grep
; вы могли бы даже сделать все это с помощью if
и goto
, если бы захотели, но тогда ваши намерения были бы захоронены под еще большим синтаксисом и отслеживанием состояния.
Ответ 2
Я постоянно использую map
и grep
. И apply
, first
, any
и многие другие из List::MoreUtils
. Я нахожу, что, в общем, они объясняют, что делает код, в отличие от того, как это делает код.
В общем, я нахожу, что, когда мой код читает то же, что и спецификация, он скорее всего будет правильным, а более вероятным будет обрабатывать случаи угла/края. Perl позволяет мне делать это намного лучше, чем любой язык, который я использовал в прошлом, и я использую его.
Например, если моя спецификация говорит, что я буду делать foo()
, если $blah
находится в некотором списке, мой код читается именно так:
foo() if any { $_ eq $blah } some_list();
Такая же идея для остальных этих инструментов. Код и спецификация выглядят устрашающе похожими, и что одна из замечательных вещей о Perl.