F# 在逐字符处理时,如何从字符串中删除字符?

F# 在逐字符处理时,如何从字符串中删除字符?,f#,F#,我对F#还相当陌生,但我正在努力找到如何正确地表示语言中的空字符有人能告诉我如何用F#表示空字符吗? 更重要的是,让我开始使用string.mapi进行字符串处理,但我不知道如何删除以下函数中的字符: let GetTargetFrameworkFolder version = let versionMapper i c = match c with | 'v' -> if i = 0 then char(0x000) else c

我对F#还相当陌生,但我正在努力找到如何正确地表示语言中的空字符有人能告诉我如何用F#表示空字符吗?

更重要的是,让我开始使用
string.mapi
进行字符串处理,但我不知道如何删除以下函数中的字符:

let GetTargetFrameworkFolder version =
    let versionMapper i c =
        match c with
        | 'v' -> if i = 0 then char(0x000) else c
        | '.' -> char(0x000)
        | _ -> c

    match version with
        | "v3.5" -> "net35"
        | "v4.0" -> "net40"        
        | "v4.5" -> "net45"  
        | vers -> vers |> String.mapi versionMapper

GetTargetFrameworkFolder "v4.5.1" |> Dump

在执行逐字符处理时,如何从字符串中删除字符,如
string.map
string.mapi

您不能使用
string.mapi
删除字符,因为此函数仅将输入中的一个字符映射到输出中的一个字符。空字符与删除字符不同;这只是另一个字符,碰巧有代码0

在您的情况下,如果我理解正确,您希望删除首字母“v”(如果有)并删除圆点。我会这样做:

let GetTargetFrameworkFolder version =
    match version with
    | "v3.5" -> "net35"
    | "v4.0" -> "net40"        
    | "v4.5" -> "net45"
    | vers ->
        let vers = if vers.[0] = 'v' then vers.[1..] else vers
        vers.Replace(".", "")

您不能使用
String.mapi
删除字符,因为此函数只将输入中的一个字符映射到输出中的一个字符。空字符与删除字符不同;这只是另一个字符,碰巧有代码0

在您的情况下,如果我理解正确,您希望删除首字母“v”(如果有)并删除圆点。我会这样做:

let GetTargetFrameworkFolder version =
    match version with
    | "v3.5" -> "net35"
    | "v4.0" -> "net40"        
    | "v4.5" -> "net45"
    | vers ->
        let vers = if vers.[0] = 'v' then vers.[1..] else vers
        vers.Replace(".", "")

删除字符时按字符处理是过滤(
string
是一个
char
序列):

let版本(s:String)=
s
|>顺序过滤器(有趣的通道->通道“.”和通道“v”)
|>字符串。Concat
更新:

要跳过第一个“v”,请执行以下操作:

let version (s: String) =
    s
    |> Seq.skip (if s.StartsWith "v" then 1 else 0)
    |> Seq.filter ((<>) '.')
    |> String.Concat
let版本(s:String)=
s
|>序号跳过(如果s.以“v”开头,则为1,否则为0)
|>序号过滤器(()'。)
|>字符串。Concat

删除字符时按字符处理是过滤(
string
是一个
char
序列):

let版本(s:String)=
s
|>顺序过滤器(有趣的通道->通道“.”和通道“v”)
|>字符串。Concat
更新:

要跳过第一个“v”,请执行以下操作:

let version (s: String) =
    s
    |> Seq.skip (if s.StartsWith "v" then 1 else 0)
    |> Seq.filter ((<>) '.')
    |> String.Concat
let版本(s:String)=
s
|>序号跳过(如果s.以“v”开头,则为1,否则为0)
|>序号过滤器(()'。)
|>字符串。Concat

如果您想保持原来的方法,另一种方法是为字符串编写自己的choose函数:

module String =

    let choosei predicate str =
        let sb = System.Text.StringBuilder()

        let choose i (c:char) = 
            match predicate i c with
                | Some(x) -> sb.Append(c) |> ignore
                | None -> ()

        str |> String.iteri choose 

        sb.ToString()
然后按如下方式使用:

let GetTargetFrameworkFolder version =
    let versionMapper i = function
        | 'v' when i = 0 -> None
        | '.' -> None
        | c -> Some(c)

    match version with
        | "v3.5" -> "net35"
        | "v4.0" -> "net40"        
        | "v4.5" -> "net45"  
        | vers -> vers |> String.choosei versionMapper

GetTargetFrameworkFolder "v4.5.1" |> Dump

如果您想保持原来的方法,另一种方法是为字符串编写自己的choose函数:

module String =

    let choosei predicate str =
        let sb = System.Text.StringBuilder()

        let choose i (c:char) = 
            match predicate i c with
                | Some(x) -> sb.Append(c) |> ignore
                | None -> ()

        str |> String.iteri choose 

        sb.ToString()
然后按如下方式使用:

let GetTargetFrameworkFolder version =
    let versionMapper i = function
        | 'v' when i = 0 -> None
        | '.' -> None
        | c -> Some(c)

    match version with
        | "v3.5" -> "net35"
        | "v4.0" -> "net40"        
        | "v4.5" -> "net45"  
        | vers -> vers |> String.choosei versionMapper

GetTargetFrameworkFolder "v4.5.1" |> Dump

您可以通过使用数组理解来实现这一点:

let GetTargetFrameworkFolder version =
    match version with
    | "v3.5" -> "net35"
    | "v4.0" -> "net40"        
    | "v4.5" -> "net45"  
    | vers -> new String([|
        for i in 0 .. vers.Length - 1 do
            match i, vers.[i] with
            | 0, 'v' | _, '.' -> () // skip 'v' at [0] and all '.'s
            | _, c -> yield c // let everything else through
    |])

您可以通过使用数组理解来实现这一点:

let GetTargetFrameworkFolder version =
    match version with
    | "v3.5" -> "net35"
    | "v4.0" -> "net40"        
    | "v4.5" -> "net45"  
    | vers -> new String([|
        for i in 0 .. vers.Length - 1 do
            match i, vers.[i] with
            | 0, 'v' | _, '.' -> () // skip 'v' at [0] and all '.'s
            | _, c -> yield c // let everything else through
    |])

感谢对1对1映射的澄清感谢对1对1映射的澄清我非常喜欢这种方法,因为它不需要我枚举字符串两次,这是
字符串的本质。替换
我非常喜欢这种方法,因为它不需要我枚举字符串两次,这是基本上发生在
string上。Replace
不是我想要的,因为这会删除所有vs.@Damian,然后只跳过第一个“v”:
let version(s:string)=s |>Seq.skip(如果s.StartsWith“v”,那么1其他0)|>Seq.filter(()”)|>String.Concat
或只使用正则表达式。这与我想要的不太一样,因为这会删除所有的vs.@Damian,然后只跳过第一个'v':
let version(s:String)=s |>Seq.skip(如果s.StartsWith“v”,那么1 else 0)|>Seq.filter(())|>String.Concat
或只使用正则表达式+1来显示收益率的用法。。。我想知道F#是否有C#的等价物yield@Damian,不客气。事实上,F#的
yield
比C#的更通用、更强大。阅读更多细节。+1用于显示产量的用法。。。我想知道F#是否有C#的等价物yield@Damian,不客气。事实上,F#的
yield
比C#的更通用、更强大。请仔细阅读以了解更多细节。