View Category
Define an empty list
Assign the variable
"list" to a list with no elements
ocaml
let list = [];;
Define a static list
Define the list
[One, Two, Three, Four, Five]
ocaml
let list = [ "One"; "Two"; "Three"; "Four"; "Five" ];;
Join the elements of a list, separated by commas
Given the list
[Apple, Banana, Carrot] produce "Apple, Banana, Carrot"
ocaml
let () =
let lst = ["Apple"; "Banana"; "Carrot"] in
let str = String.concat ", " lst in
print_endline str
let lst = ["Apple"; "Banana"; "Carrot"] in
let str = String.concat ", " lst in
print_endline str
Join the elements of a list, in correct english
Create a function join that takes a List and produces a string containing an english language concatenation of the list. It should work with the following examples:
join(
join(
join(
join(
join(
[Apple, Banana, Carrot]) = "Apple, Banana, and Carrot"
join(
[One, Two]) = "One and Two"
join(
[Lonely]) = "Lonely"
join(
[]) = ""
ocaml
let join list =
let rec join' list acc =
match list with
| [] -> ""
| [single] -> single
| one::[two] ->
if acc = "" then one ^ " and " ^ two
else acc ^ one ^ ", and " ^ two
| first::others -> join' others (acc ^ first ^ ", ")
in
join' list ""
let rec join' list acc =
match list with
| [] -> ""
| [single] -> single
| one::[two] ->
if acc = "" then one ^ " and " ^ two
else acc ^ one ^ ", and " ^ two
| first::others -> join' others (acc ^ first ^ ", ")
in
join' list ""
Produce the combinations from two lists
Given two lists, produce the list of tuples formed by taking the combinations from the individual lists. E.g. given the letters
["a", "b", "c"] and the numbers [4, 5], produce the list: [["a", 4], ["b", 4], ["c", 4], ["a", 5], ["b", 5], ["c", 5]]
ocaml
let combinations =
let l1 = ["a"; "b"; "c"]
and l2 = [4; 5] in
List.rev (
List.fold_left (fun acc y ->
List.fold_left (fun acc2 x ->
(x, y)::acc2
) acc l1
) [] l2
)
let l1 = ["a"; "b"; "c"]
and l2 = [4; 5] in
List.rev (
List.fold_left (fun acc y ->
List.fold_left (fun acc2 x ->
(x, y)::acc2
) acc l1
) [] l2
)
From a List Produce a List of Duplicate Entries
Taking a list:
Write the code to produce a list of duplicates in the list:
["andrew", "bob", "chris", "bob"]
Write the code to produce a list of duplicates in the list:
["bob"]
ocaml
let rem v lst =
let rec aux acc = function
| [] -> List.rev acc
| x::xs ->
if compare v x = 0
then aux acc xs
else aux (x::acc) xs
in
aux [] lst
(** in case of a match, returns a list with the duplicate(s) removed *)
let rec mem_rem v lst =
let rec aux acc = function
| [] -> None
| x::xs ->
if compare v x = 0
then Some(List.rev_append acc (rem v xs))
else aux (x::acc) xs
in
aux [] lst
let duplicates lst =
let rec aux acc = function
| [] -> List.rev acc
| x::xs ->
match mem_rem x xs with
| Some ret -> aux (x::acc) ret
| None -> aux acc xs
in
aux [] lst
let () =
let lst = ["andrew"; "bob"; "chris"; "bob"; "mike"; "peter"; "bob"] in
let dup = duplicates lst in
List.iter print_endline dup
let rec aux acc = function
| [] -> List.rev acc
| x::xs ->
if compare v x = 0
then aux acc xs
else aux (x::acc) xs
in
aux [] lst
(** in case of a match, returns a list with the duplicate(s) removed *)
let rec mem_rem v lst =
let rec aux acc = function
| [] -> None
| x::xs ->
if compare v x = 0
then Some(List.rev_append acc (rem v xs))
else aux (x::acc) xs
in
aux [] lst
let duplicates lst =
let rec aux acc = function
| [] -> List.rev acc
| x::xs ->
match mem_rem x xs with
| Some ret -> aux (x::acc) ret
| None -> aux acc xs
in
aux [] lst
let () =
let lst = ["andrew"; "bob"; "chris"; "bob"; "mike"; "peter"; "bob"] in
let dup = duplicates lst in
List.iter print_endline dup
(* Using standard (functorized) sets *)
module SetTools(ASet: Set.S) =
struct
let find_duplicates l =
let rec aux l seen acc =
match l with
| [] -> acc
| h :: q ->
if ASet.mem h seen then
aux q seen (h :: acc)
else
aux q (ASet.add h seen) acc in
aux l (ASet.empty) []
end
module StringSet = Set.Make(String)
module StringSetTools = SetTools(StringSet)
StringSetTools.find_duplicates ["andrew"; "bob"; "chris"; "bob"];;
module SetTools(ASet: Set.S) =
struct
let find_duplicates l =
let rec aux l seen acc =
match l with
| [] -> acc
| h :: q ->
if ASet.mem h seen then
aux q seen (h :: acc)
else
aux q (ASet.add h seen) acc in
aux l (ASet.empty) []
end
module StringSet = Set.Make(String)
module StringSetTools = SetTools(StringSet)
StringSetTools.find_duplicates ["andrew"; "bob"; "chris"; "bob"];;
Fetch an element of a list by index
Given the list
[One, Two, Three, Four, Five], fetch the third element ('Three')
ocaml
let third = List.nth [ "One"; "Two"; "Three"; "Four"; "Five" ] 3;;
Fetch the last element of a list
Given the list
[Red, Green, Blue], access the last element ('Blue')
ocaml
let list = [ "Red"; "Green"; "Blue" ] in
let last = List.nth list ( (List.length list) - 1 );;
let last = List.nth list ( (List.length list) - 1 );;
let list = [ "Red"; "Green"; "Blue" ] in
let last = List.hd (List.rev list);;
let last = List.hd (List.rev list);;
let list_last l =
let rec aux h q =
match q with
| [] -> h
| h :: q -> aux h q in
match l with
| [] -> invalid_arg "list_last"
| h :: q -> aux h q
;;
list_last ["Red"; "Green"; "Blue"]
let rec aux h q =
match q with
| [] -> h
| h :: q -> aux h q in
match l with
| [] -> invalid_arg "list_last"
| h :: q -> aux h q
;;
list_last ["Red"; "Green"; "Blue"]
Find the common items in two lists
Given two lists, find the common items. E.g. given beans =
['broad', 'mung', 'black', 'red', 'white'] and colors = ['black', 'red', 'blue', 'green'], what are the bean varieties that are also color names?
ocaml
let beans = ["broad"; "mung"; "black"; "red"; "white"]
let colors = ["black"; "red"; "blue"; "green"]
let f common c = if List.mem c beans then c::common else common
let common = List.fold_left f [] colors;;
(* common will contain a list with the common elements *)
let colors = ["black"; "red"; "blue"; "green"]
let f common c = if List.mem c beans then c::common else common
let common = List.fold_left f [] colors;;
(* common will contain a list with the common elements *)
(* using standard (functorized) sets *)
module SetTools(ASet: Set.S) =
struct
let of_list l =
List.fold_left (fun acc e -> ASet.add e acc) ASet.empty l
let find_common l1 l2 =
ASet.elements (ASet.inter (of_list l1) (of_list l2))
end
module StringSet = Set.Make(String)
module StringSetTools = SetTools(StringSet)
;;
let beans = ["broad"; "mung"; "black"; "red"; "white"] in
let colors = ["black"; "red"; "blue"; "green"] in
StringSetTools.find_common beans colors;;
module SetTools(ASet: Set.S) =
struct
let of_list l =
List.fold_left (fun acc e -> ASet.add e acc) ASet.empty l
let find_common l1 l2 =
ASet.elements (ASet.inter (of_list l1) (of_list l2))
end
module StringSet = Set.Make(String)
module StringSetTools = SetTools(StringSet)
;;
let beans = ["broad"; "mung"; "black"; "red"; "white"] in
let colors = ["black"; "red"; "blue"; "green"] in
StringSetTools.find_common beans colors;;
Display the unique items in a list
Display the unique items in a list, e.g. given ages =
[18, 16, 17, 18, 16, 19, 14, 17, 19, 18], display the unique elements, i.e. with duplicates removed.
ocaml
let ages = [18; 16; 17; 18; 16; 19; 14; 17; 19; 18]
let f res e = if List.mem e res then res else e::res
let unique = List.fold_left f [] ages;;
let f res e = if List.mem e res then res else e::res
let unique = List.fold_left f [] ages;;
(* using standard (functorized) sets *)
module SetTools(ASet: Set.S) =
struct
let of_list l =
List.fold_left (fun acc e -> ASet.add e acc) ASet.empty l
let unique l =
ASet.elements (of_list l)
end
module Integer =
struct
type t = int
let compare (x:t) y = Pervasives.compare x y
end
module IntegerSet = Set.Make(Integer)
module IntegerSetTools = SetTools(IntegerSet)
;;
IntegerSetTools.unique [18; 16; 17; 18; 16; 19; 14; 17; 19; 18];;
module SetTools(ASet: Set.S) =
struct
let of_list l =
List.fold_left (fun acc e -> ASet.add e acc) ASet.empty l
let unique l =
ASet.elements (of_list l)
end
module Integer =
struct
type t = int
let compare (x:t) y = Pervasives.compare x y
end
module IntegerSet = Set.Make(Integer)
module IntegerSetTools = SetTools(IntegerSet)
;;
IntegerSetTools.unique [18; 16; 17; 18; 16; 19; 14; 17; 19; 18];;
Remove an element from a list by index
Given the list
[Apple, Banana, Carrot], remove the first element to produce the list [Banana, Carrot]
ocaml
let delete_at i al =
if i < 0 || i >= List.length al then
invalid_arg "delete_at"
else
let rec del i l =
match l with
| [] -> []
| h::t when i = 0 -> t
| h::t -> h :: del (i-1) t
in
del i al
;;
if i < 0 || i >= List.length al then
invalid_arg "delete_at"
else
let rec del i l =
match l with
| [] -> []
| h::t when i = 0 -> t
| h::t -> h :: del (i-1) t
in
del i al
;;
let rem_first l =
match l with
| [] -> []
| h::t -> t
;;
match l with
| [] -> []
| h::t -> t
;;
List.tl ["Apple"; "Banana"; "Carrot"]
Remove the last element of a list
ocaml
let remove_last list =
match (List.rev list) with
| h::t -> List.rev t
| [] -> []
match (List.rev list) with
| h::t -> List.rev t
| [] -> []
let remove_last lst =
List.rev (List.tl (List.rev lst))
List.rev (List.tl (List.rev lst))
let list_remove_last l =
let rec aux h q acc =
match q with
| [] -> List.rev acc
| h2 :: q -> aux h2 q (h :: acc) in
match l with
| [] -> invalid_arg "list_remove_last"
| h :: q -> aux h q []
let rec aux h q acc =
match q with
| [] -> List.rev acc
| h2 :: q -> aux h2 q (h :: acc) in
match l with
| [] -> invalid_arg "list_remove_last"
| h :: q -> aux h q []
Rotate a list
Given a list
["apple", "orange", "grapes", "bananas"], rotate it by removing the first item and placing it on the end to yield ["orange", "grapes", "bananas", "apple"]
ocaml
let rotate list =
match list with
| head::tail -> tail@[head]
| [] -> []
match list with
| head::tail -> tail@[head]
| [] -> []
Gather together corresponding elements from multiple lists
Given several lists, gather together the first element from every list, the second element from every list, and so on for all corresponding index values in the lists. E.g. for these three lists, first =
['Bruce', 'Tommy Lee', 'Bruce'], last = ['Willis', 'Jones', 'Lee'], years = [1955, 1946, 1940] the result should produce 3 actors. The middle actor should be Tommy Lee Jones.
ocaml
let rec combine3 f l y =
match f, l, y with
| [], [], [] -> []
| fh :: fq, lh :: lq, yh :: yq ->
(fh, lh, yh) :: combine3 fq lq yq
| _ -> invalid_arg "combine3"
;;
let first = ["Bruce"; "Tommy Lee"; "Bruce"] in
let last = ["Willis"; "Jones"; "Lee"] in
let years = [1955; 1946; 1940] in
combine3 first last years
match f, l, y with
| [], [], [] -> []
| fh :: fq, lh :: lq, yh :: yq ->
(fh, lh, yh) :: combine3 fq lq yq
| _ -> invalid_arg "combine3"
;;
let first = ["Bruce"; "Tommy Lee"; "Bruce"] in
let last = ["Willis"; "Jones"; "Lee"] in
let years = [1955; 1946; 1940] in
combine3 first last years
List Combinations
Given two source lists (or sets), generate a list (or set) of all the pairs derived by combining elements from the individual lists (sets). E.g. given suites =
['H', 'D', 'C', 'S'] and faces = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'], generate the deck of 52 cards, confirm the deck size and check it contains an expected card, say 'Ace of Hearts'.
ocaml
let suites = ["H"; "D"; "C"; "S"]
let faces = ["2";"3";"4";"5";"6";"7";"8";"9";"10";"J";"Q";"K";"A"]
let desk =
List.fold_left (fun acc y ->
List.fold_left (fun acc2 x ->
(x, y)::acc2
) acc faces
) [] suites
let () =
assert (List.length desk = 52);
if List.mem ("A", "H") desk
then print_endline "Ace of Hearts found!"
else print_endline "Ace of Hearts not found :("
let faces = ["2";"3";"4";"5";"6";"7";"8";"9";"10";"J";"Q";"K";"A"]
let desk =
List.fold_left (fun acc y ->
List.fold_left (fun acc2 x ->
(x, y)::acc2
) acc faces
) [] suites
let () =
assert (List.length desk = 52);
if List.mem ("A", "H") desk
then print_endline "Ace of Hearts found!"
else print_endline "Ace of Hearts not found :("
Perform an operation on every item of a list
Perform an operation on every item of a list, e.g.
for the list
the list of sizes of the strings, e.g.
for the list
["ox", "cat", "deer", "whale"] calculate
the list of sizes of the strings, e.g.
[2, 3, 4, 5]
ocaml
List.map String.length ["ox"; "cat"; "deer"; "whale"];;
Split a list of things into numbers and non-numbers
Given a list that might contain e.g. a string, an integer, a float and a date,
split the list into numbers and non-numbers.
split the list into numbers and non-numbers.
ocaml
(* OCaml is a strongly statically typed language so it is not possible to mix
items of different types in a single list.
So here we use a list of strings, some of these strings represent a number *)
let is_a_number v =
try ignore(float_of_string v); true
with _ -> false
let numbers, others =
List.partition is_a_number ["Joe"; "3.14"; "8"; "hello"; "23/04/2009"]
(* ========================================================================== *)
(* If we really want to mix items of several types, we can declare a variant: *)
type item = Int of int | Float of float | String of string | Char of char
let is_a_number = function
| Float _ | Int _ -> true
| String _ | Char _ -> false
let numbers, others =
List.partition is_a_number [String "Joe"; Float 3.14; Int 8; Char 'Z']
items of different types in a single list.
So here we use a list of strings, some of these strings represent a number *)
let is_a_number v =
try ignore(float_of_string v); true
with _ -> false
let numbers, others =
List.partition is_a_number ["Joe"; "3.14"; "8"; "hello"; "23/04/2009"]
(* ========================================================================== *)
(* If we really want to mix items of several types, we can declare a variant: *)
type item = Int of int | Float of float | String of string | Char of char
let is_a_number = function
| Float _ | Int _ -> true
| String _ | Char _ -> false
let numbers, others =
List.partition is_a_number [String "Joe"; Float 3.14; Int 8; Char 'Z']
Test if a condition holds for all items of a list
Given a list, test if a certain logical condition (i.e. predicate) holds for all items of the list.
ocaml
(* from the interactive loop *)
# List.for_all (fun x -> x > 1) [2; 3; 4] ;;
- : bool = true
# List.for_all (fun x -> x > 1) [2; 3; 4] ;;
- : bool = true
Test if a condition holds for any items of a list
Given a list, test if a certain logical condition (i.e. predicate) holds for any items of the list.
ocaml
(* from the interactive loop: *)
# List.exists (fun x -> x > 3) [2; 3; 4] ;;
- : bool = true
# List.exists (fun x -> x > 3) [2; 3; 4] ;;
- : bool = true
