avoiding for loops in F#
f#, for-loop, functional-programming
Solution
As I dont grasp what you are trying to accomplish my solution is just a bit of clean up
let stringsAndNums = [("aa-",20); ("b1",20); ("aa",10); ("b12",10); ("+aa-",30)]
let results =
let split (subject, value) =
let related =
//first I created a named function for the filter expression
let filtering (osubject:string, _) = osubject.Contains(subject) || subject.Contains(osubject)
stringsAndNums |> List.filter filtering
//accessing the 2 first items of a tuple can be done via fst, snd
let relvalues = related |> List.map snd
let min = (relvalues |> List.min)
let max = (relvalues |> List.max)
//I assume you wanted to return that tuple so away with the printf
(subject, value, min, max, (max - min))
stringsAndNums |> List.map split
for result in results do
//and lastly use printfn (n-for newline) so the printing is nicer
printfn "%A" result
Problem
I have a list of strings and numbers like the following ``` let stringsAndNums = [("aa-",20); ("b1",20); ("aa",10); ("b12",10); ("+aa-",30)] ``` I need to partition the list into groups of strings that are included one in another. For each of the above groups I have to find the minimum and maximum value. This is what I have tried to do: it is working, but I don't think it is idiomatic F# and I guess I should avoid the for loops. ``` for tup in stringsAndNums do let subject, value = tup let related = stringsAndNums |> List.filter( fun o -> let osubject, ovalue = o; osubject.Contains(subject) || subject.Contains(osubject); ) let relvalues = related |> List.map(fun o -> let osubject, ovalue = o; ovalue ) let min = (relvalues |> List.min) let max = (relvalues |> List.max) printfn "%A" (subject, value, min, max, (max - min)) ``` Also, how can I define a function returning the list of tuple results instead of printing them? Desired output. The results I'm getting look fine ``` ("aa-", 20, 10, 30, 20) ("b1", 20, 10, 20, 10) ("aa", 10, 10, 30, 20) ("b12", 10, 10, 20, 10) ("+aa-", 30, 10, 30, 20) ``` In fact the two groups in this case are formed by - `+aa-` with value 30,`aa` with value 10,`aa-` with value 20, so max is 30 and min is 10 - `b1` with value 20,`b12` with value 10 My solution What I've now managed to do: there is no longer a for-loop now, but is this code truly functional? ``` let results = stringsAndNums |> List.map(fun tup -> //for tup in stringsAndNums do let subject, value = tup let related = stringsAndNums |> List.filter( fun o -> let osubject, ovalue = o; osubject.Contains(subject) || subject.Contains(osubject); ) //for reltup in related do let relvalues = related |> List.map(fun o -> let osubject, ovalue = o; ovalue ) let min = (relvalues |> List.min) let max = (relvalues |> List.max) printfn "%A" (subject, value, min, max, (max - min)) ) for result in results do printf "%A" result ```