String F#-删除字符串中第一个字符后的重复字符
我试图做的是删除字符串中特定给定字符的重复项,但保留第一个字符。即:String F#-删除字符串中第一个字符后的重复字符,string,f#,String,F#,我试图做的是删除字符串中特定给定字符的重复项,但保留第一个字符。即: let myStr = "hi. my .name." //a function that gets a string and the element to be removed in the string someFunc myStr "." 其中someFunc返回如下所示的字符串: "hi. my name" 从字符串中删除重复项很容易,但是有没有一种方法可以删除重复项,但让第一个重复的元素保留在字符串中 le
let myStr = "hi. my .name."
//a function that gets a string and the element to be removed in the string
someFunc myStr "."
其中someFunc
返回如下所示的字符串:
"hi. my name"
从字符串中删除重复项很容易,但是有没有一种方法可以删除重复项,但让第一个重复的元素保留在字符串中
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
请注意,字符是以char而不是字符串的形式给出的
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而不是字符串的形式给出的
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)
编辑:另一种方法是使用正则表达式
open System.Text.RegularExpressions
let someOtherFunc c s =
let pat = Regex.Escape(c)
Regex.Replace(s, sprintf "(?<=%s.*)%s" pat pat, "")
open System.Text.regular表达式
让其他人来=
让pat=Regex.Escape(c)
Regex.Replace(s,sprintf)(?这里有一种方法:
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."
让keepFirst c s=
Seq.mapFold(fun k c'->(c',k|cc'),k&&cc')真s
|>fst
|>顺序过滤器snd
|>序列图fst
|>A.ofSeq数组
|>系统字符串
让示例=keepFirst'.'嗨,我的名字。“
在设计函数时,考虑使其参数通用的好处。要通过迭代传递状态,禁止可变变量,Seq.scan
可能是一种选择的武器。它折叠成一个新状态元组和一个选项,然后Seq.choose
去掉状态和不需要的元素
就功能构建块而言,让它接受一个谓词函数'a->bool
,并让它返回一个函数seq
然后可以很容易地重用它来做其他事情,比如
不熟悉F#但是,您可以通过迭代字符串来创建字符列表。使用Contains方法检查字符是否已经存在。如果已经存在,请跳过,否则添加到列表Azola的想法看起来不错,但我建议改为使用集合,因为list.Contains
是O(N).使用,然后您应该能够在O(1)时间内进行查找。您能告诉我们您尝试了什么吗?
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
filterDuplicates (fun i -> i % 2 = 0) [0..10]
// val it : seq<int> = seq [0; 1; 3; 5; ...]
let filterDuplicatesOfChar what s =
System.String(Array.ofSeq <| filterDuplicates ((=) what) s)
filterDuplicatesOfChar '.' "hi. my .name."
// val it : string = "hi. my name"