0xBADF00D
0xBADF00D

Reputation: 1034

How to transform a list of string into a list of list of string in F#

I have a source list that looks like:

let source = ["A", "B", "%", "C", "Y", "%"]

I want to go through each element and each time I hit the token "%", every element of the preceding list should go into a sub list. The result should look like this.

let result = [["A", "B"], ["C", "Y"]]

I think I have to use the fold function of list, but my result type is string list instead of string list list

let folder (acc, current) item = 
        match item with
        | "" -> (current @ acc, [])
        | _ -> (acc, current @ [item])

let result = source 
            |> List.fold folder ([], []) 
            |> fun (a,_) -> a

Any ideas?

Upvotes: 3

Views: 113

Answers (2)

Robert Sim
Robert Sim

Reputation: 1560

This is not as generic but you can take advantage of string operations to do this more succinctly.

(String.concat "" source).Split([|'%'|], StringSplitOptions.RemoveEmptyEntries) 
|> List.ofArray 
|> List.map List.ofSeq

Assumes Taylor's fix to source to make it a proper list.

Upvotes: 2

Taylor Wood
Taylor Wood

Reputation: 16194

You were very close, but I think one issue was your source list was actually a list with one big tuple in it. You have to separate list items with ;. Comma , is used to separate items in a tuple.

let source = ["A"; "B"; "%"; "C"; "Y"; "%"]

Then with some minor changes to your folder function:

let folder (acc, current) item = 
  match item with
  | "%" -> (acc @ [current], [])
  | _ -> (acc, current @ [item])

You now get the result you want:

let result =
  source 
  |> List.fold folder ([], [])
  |> fst

> val result : string list list = [["A"; "B"]; ["C"; "Y"]]

Upvotes: 6

Related Questions