patternMinor
Breaking lists into subgroups in F#
Viewed 0 times
listsintosubgroupsbreaking
Problem
I'm starting to play with F# to do some data parsing and I was able to create a function to group an array of string into sub groups. The code looks like this:
However, I feel that it could be improved specially regarding the way I handle intermediate values when concatenating the lists and the data structure used to return the grouped data.
The goal, at the end, is to insert each of these "groups" as single entities in the database. Is there a more suitable data structure that I should take a look?
Below is a sample ready to be used and an example output.
Any suggestions are appreciated.
let breakBy lines pattern =
let rec breakByRec lines pattern acc =
match lines with
| [] -> acc
| head::tail ->
match pattern head with
| true ->
let newGroup = [head]
let newList = newGroup :: acc
breakByRec tail pattern newList
| false ->
let lastGroup = List.head acc
let newGroup = head :: lastGroup;
let newList = newGroup :: List.tail acc
breakByRec tail pattern newList
breakByRec lines pattern [[]]However, I feel that it could be improved specially regarding the way I handle intermediate values when concatenating the lists and the data structure used to return the grouped data.
The goal, at the end, is to insert each of these "groups" as single entities in the database. Is there a more suitable data structure that I should take a look?
Below is a sample ready to be used and an example output.
let data = [
"Name=John"; "Age=29"; "City=San Francisco";
"Name=Jane"; "Age=28"; "City=New York";
"Name=Mike"; "Age=35"; "City=Miami"
]
let matchName line = Regex.IsMatch(line, "^Name=")
let people = breakBy data matchName
printfn "%A" people
/*
The output looks like this:
val people : string list list = [
["City=Miami"; "Age=35"; "Name=Mike"];
["City=New York"; "Age=28"; "Name=Jane"];
["City=San Francisco"; "Age=29"; "Name=John"];
[]
]
*/Any suggestions are appreciated.
Solution
The fact that a function named
breakBy also reverses the order of the data violates the Principle of Least Surprise. In my opinion, it's a bug.breakBy (Regex "^Name=").IsMatch can be thought of as an transformation to be applied to a list. Therefore, to facilitate currying, the order of the parameters to breakBy should be reversed, so that the predicate comes before the data.Context
StackExchange Code Review Q#124060, answer score: 2
Revisions (0)
No revisions yet.