Home > database >  Function to split a list of strings into group of strings on specific element value
Function to split a list of strings into group of strings on specific element value

Time:12-06

I'm trying to create a function for the following:

Given a list of strings ["abceadfapaq"; "asdqwedasca"; " "; "asdasqyhgahfgasdsadasda"] and a string separator " " returns another list with sublists splitted on the desired separator. [["abceadfapaq"; "asdqwedasca"]; ["asdasqyhgahfgasdsadasda"]]

I've implemented two functions to achieve this, one of them failing because it cannot handle the separator to be an empty space " "

Failing:

let groupWithNoReplace (inputLines: string list) (separator: string) =
        let complete = 
            seq {
                for line in inputLines do
                    yield! line.Split(' ')
            } |> List.ofSeq
        let folder (a) (cur, acc) = 
            match a with
            | _ when a <> separator -> a::cur, acc
            | _ -> [], cur::acc 
        let result = List.foldBack folder (complete) ([], [])
        (fst result)::(snd result)

let groupWithNoReplace0 = 
    groupWithNoReplace ["abceadfapaq"; "asdqwedasca"; " "; "asdasqyhgahfgasdsadasda"] " "

val groupWithNoReplace0: string list list =
  [["abceadfapaq"; "asdqwedasca"; ""; ""; "asdasqyhgahfgasdsadasda"]]

let groupWithNoReplace00 = 
    groupWithNoReplace ["abceadfapaq"; "asdqwedasca"; "="; "asdasqyhgahfgasdsadasda"] "="

val groupWithNoReplace00: string list list =
  [["abceadfapaq"; "asdqwedasca"]; ["asdasqyhgahfgasdsadasda"]]

So the second function is the same but replacing the empty space with a symbol I don't think it would appear in the input "§" I don't like this solution as I don't want to force the input to fullfil specific requeriments based on my implementation.

Working with replace

let groupWithNoReplace (inputLines: string list) (separator: string) =
        let validlines = inputLines |> List.map(fun e -> if e = " " then "§" else e)
        let validsplitter =
            match separator = " " with
            | true -> "§"
            | false -> separator
        let complete = 
            seq {
                for line in validlines do
                    yield! line.Split(' ')
            } |> List.ofSeq
        let folder (a) (cur, acc) = 
            match a with
            | _ when a <> validsplitter -> a::cur, acc
            | _ -> [], cur::acc
                
        let result = List.foldBack folder (complete) ([], [])
        (fst result)::(snd result)

let groupWithNoReplace1 = 
    groupWithNoReplace 
["abceadfapaq"; "asdqwedasca"; " "; "asdasqyhgahfgasdsadasda"] " "

val groupWithNoReplace1: string list list =
  [["abceadfapaq"; "asdqwedasca"]; ["asdasqyhgahfgasdsadasda"]]

let groupWithNoReplace11 = 
    groupWithNoReplace ["abceadfapaq"; "asdqwedasca"; "="; "asdasqyhgahfgasdsadasda"] "="

val groupWithNoReplace11: string list list =
  [["abceadfapaq"; "asdqwedasca"]; ["asdasqyhgahfgasdsadasda"]]

CodePudding user response:

this should work:

let splitWhen predicate list =
    let folder state t =
        if predicate t then
            [] :: state
        else
            (t :: state.Head) :: state. Tail

    list 
    |> List.fold folder [ [] ] 
    |> List.map List.rev
    |> List.rev
  • Related