Лямбда-выражения
Лямбда-выражение — это безымянная функция, которую можно сохранить в переменной или передать другой функции как аргумент.
Виды лямбда-выражений
В PascalABC.NET удобно выделять три основных вида лямбда-выражений:
- лямбда-преобразование — преобразует исходное значение в новое:
x -> x * x; - лямбда-условие — определяет, выполняется ли условие для значения:
x -> x mod 2 = 0; - лямбда-проекция — преобразует составной объект в одну из его частей:
x -> x.Age.
Переменная функционального типа
Переменная функционального типа может хранить лямбда-выражение; тип такой переменной должен указываться явно.
begin
var f: real -> real := x -> x*x;
var pred: (real,real) -> boolean := (x,y) -> x < y;
f(5).Print;
pred(3,2).Print;
end.
Результат:
25 False
Лямбда-преобразование
Лямбда-преобразование вычисляет новое значение по исходному элементу, сохраняя или изменяя его тип.
begin
var a := Arr(1..5);
var squares := a.Select(x -> x * x);
squares.Println;
end.
Результат:
1 4 9 16 25
Лямбда-преобразование может возвращать значение другого типа.
begin
var a: array of integer := Arr(1..5);
var strings: array of string := a.Select(x -> x.ToString).ToArray;
strings.Println;
end.
Результат:
1 2 3 4 5
Лямбда-условие
Лямбда-условие возвращает логическое значение для заданного значения и используется для отбора элементов по заданному критерию.
begin
var a := Arr(1..10);
var even := a.Where(x -> x mod 2 = 0);
even.Println;
end.
Результат:
2 4 6 8 10
Лямбда-проекция
Лямбда-проекция преобразует составной объект в одну из его частей.
begin
var items := [
('apple',1.5),
('banana',1.2),
('cherry',0.9)
];
var names := items.Select(x -> x.Item1);
names.Println;
end.
Результат:
apple banana cherry
Лямбда как параметр функции
Лямбда передаётся в функцию как параметр и применяется к каждому элементу массива.
Обобщённая функция Transform может преобразовывать массив элементов одного типа в массив элементов другого типа.
function Transform<T,T1>(a: array of T; f: T -> T1): array of T1;
begin
Result := new T1[a.Length];
for var i := 0 to a.Length - 1 do
Result[i] := f(a[i]);
end;
begin
var a := [1,2,3,4,5];
Transform(a, x -> x*x).Println;
Transform(a, x -> $'#{x}').Println;
Transform(a, x -> x.IsEven).Println;
end.
Результат:
1 4 9 16 25
#1 #2 #3 #4 #5
False True False True False
Условие и преобразование в одной цепочке
Лямбда-условия и лямбда-преобразования можно последовательно применять к одной последовательности.
begin
var a := Arr(1..10);
a.Where(x -> x mod 2 = 0)
.Select(x -> x * x)
.Println;
end.
Результат:
4 16 36 64 100
Сначала Where отбирает элементы по условию, затем Select преобразует отобранные значения.
Генерация массива по индексу
ArrGen создаёт массив, вычисляя каждый элемент по его индексу с помощью лямбда-преобразования.
begin
var a := ArrGen(10,i -> i*i,1);
a.Println;
end.
Результат:
1 4 9 16 25 36 49 64 81 100
Генерация массива по предыдущему значению
ArrGen позволяет создавать последовательность, в которой каждый следующий элемент вычисляется из предыдущего.
begin
var a := ArrGen(10,1,x -> x*2);
a.Println;
end.
Результат:
1 2 4 8 16 32 64 128 256 512