listcountocamlrecord

How to count records of a list with a specific property in OCaml?


Lets say we have a record which defines a person type with the properties name and age:

type person = {name:string ; age:int };;

and initialize a list with different types:

let personlist = [{name="alexander";age=21};{name="benjamin";age=30};{name="claudia";age=21}];;

How can I count the amount of types with a specific age, lets say 21 (alexander and claudia) so that the output in this case would be two?


Solution

  • The most straightforward way would be to combine List.length and List.filter.

    List.(personlist |> filter (fun p -> p.age = 21) |> length)
    

    However, this is somewhat less efficient than it could be. We can do it in one pass because we don't really need to build a list of the matching people, and then iterate over that list to find its length.

    List.fold_left will let us iterate over personlist, updating the initial value of 0 on each iteration dependent on whether the age field of each record is 21 or not.

    List.fold_left (fun i {age; _} -> i + if age = 21 then 1 else 0) 0 personlist
    

    This can be generalized as a count function which takes a predicate function as an argument.

    let count p lst = 
      lst 
      |> List.fold_left (fun i x -> i + Bool.to_int (p x)) 0