Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count occurrences of an element in a list

Tags:

f#

I have a list of integers and any integers that occur multiple times will do so consecutively. I would like to convert this to a list of tuples, containing each object together with its count.

I have come up with the below, but there is a problem with the return type of temp: "The type 'int' does not match the type ''a list'". However, the three return types look consistent to me. What have I done wrong? If what I've done is not good F# and should be done in a completely different way, please also let me know.

let countoccurences list =
    match list with
    | x::xs -> let rec temp list collecting counted =
                    match list with
                    | x::xs when x=collecting -> temp xs collecting counted+1
                    | x::xs -> (collecting,counted)::temp xs x 1
                    | [] -> (collecting,counted)::[]
               temp xs x 1
    | [] -> []
like image 268
mollmerx Avatar asked Feb 22 '11 21:02

mollmerx


2 Answers

EDIT: Oops, this does not answer your question, since you said "consecutive". But I'll leave it here since someone searching the question title may find it useful.

Seq.countBy does this.

let list = [1;2;3;4;5;6;1;2;3;1;1;2]
let results = list |> Seq.countBy id |> Seq.toList 
printfn "%A" results
// [(1, 4); (2, 3); (3, 2); (4, 1); (5, 1); (6, 1)]
like image 104
Alberto Millan Avatar answered Oct 07 '22 19:10

Alberto Millan


What about this one?

lst |> Seq.groupBy (fun x -> x) |> Seq.map (fun (a,b) -> (a, Seq.length(b)))
like image 24
Nyi Nyi Avatar answered Oct 07 '22 19:10

Nyi Nyi