2017-03-21 27 views
0

我已经看到这个问题的其他答案,但我只是想以不同的方式做。然而无论我做什么,我都不能让我的类型匹配如何编写函数来评估String是否只有字符?

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 

} 

我不得不做的所有设置,字符,字符串数组转换,但仍无法得到它的权利:(。

不能调用类型“字符”初始化与参数列表类型的 '((String.CharacterView._Element))'

+1

怎么样'如果trimmed.rangeOfCharacter(from:letters.inverted)== nil'? –

+2

请注意'CharacterSet'和'Set '是不同的类型,所以计算'wordCharactersSet.intersection(letters)'的方法不能工作。 –

+1

单行解决方案'return word.trimmingCharacters(in:.whitespaces).rangeOfCharacter(from:CharacterSet.letters。倒数)== nil' –

回答

2

您的代码

let characterViewArray = Array(trimmed.characters) 

已经创建了一个Array<Character>,所以你可以简单跳过 下一行,并创建一个Set<Character>

let wordCharactersSet = Set(characterViewArray) 

但是,这并不能真正帮助,因为Set<Character>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) 
} 
+0

因此,如果你想使用'CharacterSet'和'Set ',然后使用'CharacterSet(charactersIn:_)'将'Set'转换为'CharacterSet',那么它会是正确的。' – Honey

+0

@ Honey:'CharacterSet(charactersIn:_)'接受'String'作为参数,所以你可以直接传递字符串,而不需要创建一个'Set '。 –

+0

是的,对不起我的错误....现在唯一的问题是我无法对'CharacterSet'执行'.count'。有什么解决方法吗?我当前的解决方案是'let intersection = letters.intersection(CharacterSet(charactersIn:trimmed))return intersection.count == characterViewArray.count'只有''intersection'上的'.count'不起作用,因为'CharacterSet's不用没有数...... – Honey

1

由于MartinR指出, CharacterSet不等于Set<Character>

我能得到你原来的解决方案最接近的是从修剪字符串创建一个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)) 
    ) 
} 

这么说,我想我还是会与马丁的解决方案去:

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

更直观。

+0

你的解决方案对'containsOnlyAlphabets(“Thanks David”)''返回false。有些东西似乎是错误的,它如何处理空格 – Honey

+1

@Honey:'word.trimmingCharacters'(如你的问题)只从字符串的两端删除空格,而不是* all *空格。如果你想允许任意的空格,那么最简单的解决方案是将它添加到允许的字符集中。 –

+0

@MartinR非常感谢你,跟着你说的使用'letters.insert(“”)',它不再返回false – Honey

相关问题