我有一个字符串,它只应包含字母。为了检查这一点,我编写了以下代码:
let isCorrectString(str:string) =
let isInRange x = (x > 64 && x < 91 ) || (x > 96 && x < 123) || x = 32
not (str.Any(fun ch -> not (isInRange (ch :?> int)) ))
显然我在这里使用了LINQ的`Any'扩展方法。有没有更好的方法来编写上面的代码?
我有一个字符串,它只应包含字母。为了检查这一点,我编写了以下代码:
let isCorrectString(str:string) =
let isInRange x = (x > 64 && x < 91 ) || (x > 96 && x < 123) || x = 32
not (str.Any(fun ch -> not (isInRange (ch :?> int)) ))
显然我在这里使用了LINQ的`Any'扩展方法。有没有更好的方法来编写上面的代码?
如果你只是想验证它是否正确,可以这样做:
let isCorrectString(str:string) =
let isInRange x = (x > 64 && x < 91 ) || (x > 96 && x < 123) || x = 32
let bad =
str
|> Seq.map (fun c -> isInRange(int c))
|> Seq.exists (fun b -> b = false)
not bad
let isCorrectString(str:string) =
str
|> Seq.forall (fun c -> System.Char.IsLetter(c) || c = ' ')
let isCorrectString(str:string) =
str
|> Seq.tryFind (fun c -> not(System.Char.IsLetter(c) || c = ' '))
|> Option.isNone
Seq.exists
双重否定后等同于 Seq.forall
,是吗?因此 let isCorrectString : string -> bool = Seq.forall (fun c -> System.Char.IsLetter c || System.Char.IsWhiteSpace c)
或者其他什么东西。 - kaeferString.forall
,你可以部分应用它来得到 let isCorrectString = String.forall (fun c -> System.Char.IsLetter(c) || c = ' ')
。该函数的作用是对字符串中的每个元素执行给定的谓词函数并返回一个布尔值,表示所有元素是否都满足谓词函数的条件。在这里,谓词函数是一个lambda表达式,判断字符是否为字母或空格。 - DanielString.forall
在逐个字符处理字符串时比 Seq.forall
快得多,特别是当字符串相对较小的时候。 - latkinChar.IsLetter
并不等同于检查 a-z + A-Z
。 IsLetter
匹配了许多非英语字符(例如: 'Dž'
,'ʰ'
,'ˁ'
)。因此,它比手动检查 (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
要慢一些。 - latkin