OCaml
Przetwarzanie listy
Szukaj…
Lista.Mapa
List.map ma sygnaturę ('a -> 'b) -> 'a list -> 'b list która w języku angielskim jest funkcją, która przejmuje funkcję (nazywamy to funkcją mapowania) jednego typu (mianowicie 'a ) do innego typu (mianowicie 'b ) i wykaz pierwszego typu. Funkcja zwraca listę drugiego typu, w której każdy element jest wynikiem wywołania funkcji mapowania na elemencie pierwszej listy.
List.map string_of_int [ 1; 2; 3; 4 ]
#- [ "1"; "2"; "3"; "4" ] : string list
Typy 'a a 'b i 'b nie muszą być różne. Na przykład możemy równie łatwo mapować liczby na ich kwadraty.
let square x = x * x in
List.map square [ 1; 2; 3; 4 ]
#- [ 1; 4; 9; 16 ] : int list
Agreguj dane na liście
Funkcje List.fold_left i List.fold_right są funkcjami wyższego rzędu, które implementują zewnętrzną logikę agregacji list. Agregowanie listy, czasami nazywane również zmniejszaniem listy, oznacza obliczenie wartości uzyskanej z sekwencyjnej kontroli wszystkich pozycji na tej liście.
Dokumentacja modułu List stwierdza, że
-
List.fold_left fa [b1; ...; bn]tof (... (f (fa b1) b2) ...) bn. -
List.fold_right f [a1; ...; an] boznaczaf a1 (f a2 (... (f an b) ...)). (Ta ostatnia funkcja nie jest rekurencyjna).
W prostym języku angielskim List.fold_left fa [b1; ...; bn] oznacza przeglądanie listy [b1; ...; bn] śledzenie akumulatora początkowo ustawiona na : za każdym razem widzimy pozycję na liście, używamy a f zaktualizować wartość w akumulatorze, a kiedy skończysz, akumulator jest ostateczna wartość naszych obliczeń. Funkcja List.fold_right jest podobna.
Oto kilka praktycznych przykładów:
Oblicz całkowitą sumę listy liczb
List.fold_left ( + ) 0 lst
Oblicz średnią z listy liczb zmiennoprzecinkowych
let average lst =
let (sum, n) =
List.fold_left (fun (sum, n) x -> (sum +. x, n + 1)) (0.0, 0) lst
in
sum /. (float_of_int n)
Ponownie zaimplementuj podstawowe przetwarzanie listy
Funkcje List.fold_left i List.fold_right są tak ogólne, że można ich używać do implementacji prawie wszystkich innych funkcji z modułu list:
let list_length lst = (* Alternative implementation to List.length *)
List.fold_left ( + ) 0 lst
let list_filter predicate lst = (* Alternative implementation to List.filter *)
List.fold_right (fun a b -> if predicate a then a :: b else b) lst []
Możliwe jest nawet List.iter funkcji List.iter , pamiętaj, że () jest globalnym stanem programu, który interpretuje ten kod jako kolejny przykład agregacji listy :
let list_iter f lst = (* Alternation implementation to List.iter *)
List.fold_left (fun () b -> f b) () lst
Te przykłady mają być materiałem do nauki, te implementacje nie mają cnoty nad odpowiednimi funkcjami ze standardowej biblioteki.