2017-03-21 28 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

相關問題