2015-12-25 44 views
1

我试图文件名转换如下所示:在F#字符串转换

ten_of_clubs.png

10_of_clubs.png

但是,我不喜欢我的实现:

let getFile (card: Card Option) = 
    let fileName = 
     match card with 
     | Some card -> (getUnionTypeName card.Face + "_of_" + getUnionTypeName card.Suit + ".png").ToLower() 
     | None -> "" 

    let delimitedName = fileName.Split '_' 
    let currentFace = delimitedName.[0] 
    let updatedFace = 
     match currentFace with 
     | "two" -> "2" 
     | "three" -> "3" 
     | "four" -> "4" 
     | "five" -> "5" 
     | "six" -> "6" 
     | "seven" -> "7" 
     | "eight" -> "8" 
     | "nine" -> "9" 
     | "ten" -> "10" 
     | _ -> currentFace 
    updatedFace + "_" + delimitedName.[1] + "_" + delimitedName.[2] 

在F#中,如何才能在不引用所有元素的情况下更改字符串的第一个元素?

例子:

updatedFace + "_" + delimitedName.[1] + "_" + delimitedName.[2] 

updatedFace + "_" + delimitedName.[1..] 

回答

2

没有理由首先构造一个格式化的字符串,然后拆分它,最后创建一个新的格式化的字符串。

假设你的意图是在None情况下返回空字符串,你可以做这样的事情:

let getFile card = 
    let digitize candidate = 
     match candidate with 
     | "Two" -> "2" 
     | "Three" -> "3" 
     | "Four" -> "4" 
     | "Five" -> "5" 
     | "Six" -> "6" 
     | "Seven" -> "7" 
     | "Eight" -> "8" 
     | "Nine" -> "9" 
     | "Ten" -> "10" 
     | _ -> candidate 
    match card with 
    | Some c -> 
     let face = c.Face |> string |> digitize 
     let suit = c.Suit |> string 
     sprintf "%s_of_%s.png" face suit 
    | None -> "" 

这里,我假定FaceSuit类型覆盖ToString,而不是依赖在我不知道的名为getUnionTypeName的函数上。这使您能够使用内置功能string(它简单地调用ToString())。

特设测试:

> Some { Face = Ten; Suit = Clubs } |> getFile;; 
val it : string = "10_of_Clubs.png" 
> Some { Face = Jack; Suit = Clubs } |> getFile;; 
val it : string = "Jack_of_Clubs.png" 
> None |> getFile;; 
val it : string = "" 

digitize功能看起来像一个通用功能的候选人,我不知道如果BCL还没有类似的东西在其全球化命名空间躺在附近。 ..否则,我敢肯定,有数以百计的NuGet包在那里,实现这样的功能...


事实证明,有数以百计的NuGet的包THA t已经这样做了,所以我创建了一个名为Numsense。有了它,您可以将getFile函数简化为:

open Ploeh.Numsense 

let getFile card = 
    let digitize candidate = 
     match Numeral.tryParseEnglish candidate with 
     | Some i -> string i 
     | None -> candidate 
    match card with 
    | Some c -> 
     let face = c.Face |> string |> digitize 
     let suit = c.Suit |> string 
     sprintf "%s_of_%s.png" face suit 
    | None -> "" 
1

由_你得到部分的阵列分裂您的字符串后。数组是可变集合。您可以通过函数更改First,然后再通过_连接。

let parts = myString.Split [|'_'|] 
parts.[0] <- toNumber parts.[0] 
String.concat "_" parts