F # - delete duplicate characters after the first in a string

What I'm trying to do is remove duplicates of a specific given char in a string, but leave the first char. Ie:

let myStr = "hi. my .name."

//a function that gets a string and the element to be removed in the string
someFunc myStr "."  

where someFuncreturns the string showen, as shown below:

"hi. my name"

It's easy to remove duplicates from a row, but is there a way to remove duplicates, but leave the first duplicate element in the row?

+3
source share
4 answers

Here is one approach:

let keepFirst c s =
    Seq.mapFold (fun k c' -> (c', k||c<>c'), k&&c<>c') true s
    |> fst
    |> Seq.filter snd
    |> Seq.map fst
    |> Array.ofSeq
    |> System.String

let example = keepFirst '.' "hi. my .name."
+4
source
let someFunc (str : string) c =
    let parts = str.Split([| c |])
    if Array.length parts > 1 then
        seq {
            yield Array.head parts
            yield string c
            yield! Array.tail parts
        }
        |> String.concat ""
    else
        str

Note that the character is assigned as char instead of a string.

+2
source
let someFunc chr (str:string) =
    let rec loop (a: char list) b = function
        | [] -> a |> List.rev |> System.String.Concat
        | h::t when h = chr -> if b then loop a b t 
                               else loop (h::a) true t
        | h::t -> loop (h::a) b t
    loop [] false (str.ToCharArray() |> Array.toList)

, char .

: -

open System.Text.RegularExpressions

let someOtherFunc c s =
    let pat = Regex.Escape(c)
    Regex.Replace(s, sprintf "(?<=%s.*)%s" pat pat, "")

, .

2:

let oneMoreFunc (c:char) (s:string) =
    let pred = (<>) c
    [ s |> Seq.takeWhile pred
      seq [c]
      s |> Seq.skipWhile pred |> Seq.filter pred ]
    |> Seq.concat
    |> System.String.Concat
+2

, . , , Seq.scan . , Seq.choose .

, 'a -> bool seq<'a> -> seq<'a>.

let filterDuplicates predicate =
    Seq.scan (fun (flag, _) x ->
        let p = predicate x in flag || p,
        if flag && p then None else Some x ) (false, None)
    >> Seq.choose snd

, , 0 .

filterDuplicates (fun i -> i % 2 = 0) [0..10]
// val it : seq<int> = seq [0; 1; 3; 5; ...]

System.String, , char -> seq<char> -> System.String.

let filterDuplicatesOfChar what s = 
    System.String(Array.ofSeq <| filterDuplicates ((=) what) s)
filterDuplicatesOfChar '.' "hi. my .name."
// val it : string = "hi. my name"
0

Source: https://habr.com/ru/post/1673627/


All Articles