map используется для создания списка путем преобразования элементов другого списка.
grep используется для создания списка путем фильтрации элементов другого списка.
sort используется для создания списка путем сортировки элементов другого списка.
Каждый из этих операторов получает блок кода (или выражение), который используется для преобразования, фильтрации или сравнения элементов списка.
Для map результатом блока становится один (или более) элемент (ов) в новом списке. Текущий элемент имеет псевдоним $ _.
Для grep логический результат блока решает, будет ли элемент исходного списка скопирован в новый список. Текущий элемент имеет псевдоним $ _.
Для sort блок получает два элемента (с псевдонимами $ a и $ b) и, как ожидается, вернет один из -1, 0 или 1, указывая, больше ли $ a, равно или меньше чем $ b.
Преобразование Шварца использует эти операторы для эффективного кэширования значений (свойств), которые будут использоваться при сортировке списка, особенно когда вычисление этих свойств имеет нетривиальную стоимость.
Он работает путем создания промежуточного массива, который имеет в качестве элементов ссылки на массив с исходным элементом и вычисленным значением, по которому мы хотим отсортировать. Этот массив передается для сортировки, которая сравнивает уже вычисленные значения, создавая другой промежуточный массив (этот отсортирован), который, в свою очередь, передается на другую карту, которая выбрасывает кэшированные значения, тем самым восстанавливая массив до его начальных элементов списка (но в нужном порядке).
Пример (создает список файлов в текущем каталоге, отсортированный по времени их последнего изменения):
@file_list = glob('*');
@file_modify_times = map { [ $_, (stat($_))[8] ] } @file_list;
@files_sorted_by_mtime = sort { $a->[1] <=> $b->[1] } @file_modify_times;
@sorted_files = map { $_->[0] } @files_sorted_by_mtime;
Объединяя операторы вместе, для промежуточных массивов объявление переменных не требуется;
@sorted_files = map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [ $_, (stat($_))[8] ] } glob('*');
Вы также можете отфильтровать список перед сортировкой, вставив grep (если вы хотите фильтровать по тому же кешированному значению):
Пример (список файлов, измененных за последние 24 часа, отсортированный по времени последнего изменения):
@sorted_files = map { $_->[0] } sort { $a->[1] <=> $b->[1] } grep { $_->[1] > (time - 24 * 3600 } map { [ $_, (stat($_))[8] ] } glob('*');