Курс по Raku / Функционално, паралелно, реактивно и уеб програмиране / Функционално програмиране / Свиване
Процедурата reduce
Когато искате да свиете със собствена операция, а не с един именуван
оператор, използвайте процедурата reduce. Тя приема блок от
два аргумента и го прилага по списъка, носейки текущия резултат
нататък:
say (1..5).reduce(* + *); # 15Блокът * + * има две звезди Whatever: първата е резултатът дотук,
втората е следващият елемент. Затова reduce изчислява
((((1 + 2) + 3) + 4) + 5), тоест 15 — същото
като [+], но записано с блок.
За да видите тези два аргумента в действие, дайте им имена и
отпечатайте всяка стъпка. Острият блок връща последния си израз, така че
$x + $y е и онова, за което блокът печата, и стойността,
която той връща на reduce:
say (1..5).reduce(
-> $x, $y {
say "$x + $y";
$x + $y;
}
);Това отпечатва:
1 + 2
3 + 3
6 + 4
10 + 5
15Всеки от първите четири реда е едно извикване на блока.
$x е резултатът, натрупан дотук, а $y е
следващият елемент от списъка. Най-първото извикване получава първите
две стойности на списъка — 1 и 2; всяко
следващо получава обратно сбора от предишната стъпка като
$x — 3, после 6, после
10 — в двойка със следващото число като $y.
Стойността на блока става $x на следващото извикване, а
крайният сбор 15 е онова, което reduce връща и
say отпечатва на последния ред.
Понеже блокът може да е какъвто и да е, reduce е по-общ.
Например можете да изградите стойност стъпка по стъпка:
say (1..4).reduce(-> $acc, $x { $acc * 10 + $x }); # 1234Всяка стъпка умножава акумулатора по десет и добавя следващата цифра,
превръщайки отделните цифри 1, 2, 3, 4 в числото
1234.
Както и другите методи, приемащи блок, reduce се чете
добре във формата извикване с
двоеточие, която маха скобите около блока:
say (1..5).reduce: * + *; # 15Накратко: [op] е бързата форма за именуван оператор, а
reduce — гъвкавата форма за произволен обединяващ блок. И
двете свеждат списък до една стойност.
Практика
Направете 1 тест върху съдържанието на тази тема.
Навигация в курса
← Тест — Метаоператорът за свиване | Тест — Свиване →
💪 Или преминете направо към упражненията в този
раздел.