【问题标题】:how to write function to evaluate if String is only characters?如何编写函数来评估字符串是否只是字符?
【发布时间】:2017-03-21 20:40:39
【问题描述】:

我已经看到了这个问题的其他答案,但我只是想以不同的方式来做。然而,无论我做什么,我都无法让我的类型匹配

func ContainsOnlyAlphabets(_ word : String) -> Bool{
    let letters = CharacterSet.letters // Set<Character>

    let trimmed = word.trimmingCharacters(in: .whitespaces)

    let characterViewArray = Array(trimmed.characters) // Array<characterView>
    let characterArray = characterViewArray.map{Character($0)} // Error: Can't create Chars
    let wordCharactersSet = Set(characterArray) // Set<Character>

    let intersection = wordCharactersSet.intersection(letters)

    return intersection.count == characterArray.count

}

我必须进行所有的 Set、Char、String、Array 转换,但仍然无法正确处理 :(.

无法使用参数列表调用类型“Character”的初始化程序 '((String.CharacterView._Element))' 类型的

【问题讨论】:

  • if trimmed.rangeOfCharacter(from: letters.inverted) == nil 呢?
  • 注意CharacterSetSet&lt;Character&gt;是不同的类型,所以你的计算wordCharactersSet.intersection(letters)的方法不能工作。
  • 一条线解决方案return word.trimmingCharacters(in: .whitespaces).rangeOfCharacter(from: CharacterSet.letters.inverted) == nil

标签: swift string set character characterview


【解决方案1】:

你的代码

let characterViewArray = Array(trimmed.characters)

已经创建了一个Array&lt;Character&gt;,所以你可以简单地跳过 下一行并使用

创建一个Set&lt;Character&gt;
let wordCharactersSet = Set(characterViewArray)

但这并没有真正的帮助,因为Set&lt;Character&gt;CharacterSet 是不同的类型,所以

let intersection = wordCharactersSet.intersection(letters)

不编译。可能的替代方案是

return trimmed.rangeOfCharacter(from: letters.inverted) == nil

return CharacterSet(charactersIn: trimmed).isSubset(of: letters)

如果您的意图是同时允许字母 空白字符 那么它可能看起来像这样:

func containsOnlyLettersAndWhitespace(_ word : String) -> Bool{
    var allowedSet = CharacterSet.letters
    allowedSet.formUnion(CharacterSet.whitespaces)

    return word.rangeOfCharacter(from: allowedSet.inverted) == nil
    // Alternatively:
    return CharacterSet(charactersIn: word).isSubset(of: allowedSet.inverted)
}

【讨论】:

  • 所以说如果你想使用CharacterSets & Set&lt;Character&gt; 然后将Set 转换为CharacterSet 使用CharacterSet(charactersIn:_) 是正确的
  • @Honey: CharacterSet(charactersIn:_)String 作为参数,因此您可以直接传递字符串,而无需创建Set&lt;Character&gt;
  • 是的,对不起我的错误......我现在唯一的问题是我不能在CharacterSet 上做.count。有什么解决方法吗?我目前的解决方案是let intersection = letters.intersection(CharacterSet(charactersIn:trimmed)) return intersection.count == characterViewArray.count 只是intersection 上的.count 不起作用,因为CharacterSets 没有计数...
  • @Honey:这就是我建议isSubset(of:)rangeOfCharacter(from:) 的原因——你不再需要数组了。 (intersection 是一个 CharacterSetcharacterViewArray 一个数组,你不能比较它们)
  • @actually 是的,看到 David Barry 的解决方案,我意识到将两个 sets 与 count 进行比较是愚蠢的。比较sets 本身就足够了。
【解决方案2】:

正如 MartinR 所说,CharacterSet 不等于 Set&lt;Character&gt;

我能找到的最接近您原始解决方案的方法是从修剪后的字符串创建一个 CharacterSet 并将您的一些原始算法应用于该:

func ContainsOnlyAlphabets(_ word : String) -> Bool{
    let letters = CharacterSet.letters

    let trimmed = word.trimmingCharacters(in: .whitespaces)
    let wordCharacterSet = CharacterSet(charactersIn:trimmed)

    let intersection = wordCharacterSet.intersection(letters)

    return intersection == wordCharacterSet
}

严格保持在CharacterSet 的范围内并对其进行操作,您还可以使用:

func ContainsOnlyAlphabets(_ word : String) -> Bool{
    return CharacterSet.letters.isSuperset(of:
        CharacterSet(charactersIn: word.trimmingCharacters(in: .whitespaces))
    )
}

也就是说,我想我还是会选择 Martin 的解决方案:

func ContainsOnlyAlphabets(_ word : String) -> Bool{
    return word
        .trimmingCharacters(in: .whitespaces)
        .rangeOfCharacter(from: CharacterSet.letters.inverted) == nil
}

因为更直观。

【讨论】:

  • 您的解决方案为 containsOnlyAlphabets("Thanks David") 返回 false。它处理空白的方式似乎有问题
  • @Honey: word.trimmingCharacters (如您的问题)仅从字符串的两端删除空格,而不是 all 空格。如果您想允许任意空格,那么最简单的解决方案是将其添加到允许的字符集中。
  • @MartinR 非常感谢,按照你所说的使用letters.insert(" "),它不再返回 false
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多