2017-07-28 142 views
1

我試圖用rangeOfCharacter創建一個應用程序,但我無法理解它的文檔:在使用rangeOfCharacter的雨燕3.0

func rangeOfCharacter(from: CharacterSet, options: 
String.CompareOptions, range: Range<String.Index>?) 

-Finds and returns the range in the String of the first character from 
a given character set found in a given range with given options. 

文檔鏈接:https://developer.apple.com/documentation/swift/string#symbols

我正在練習合作創建一個函數,它將採用一個名稱並返回名稱,在第一個元音之前減去任何輔音。如果在第一個元音之前沒有輔音,則該名稱應該保持不變。

下面是我到目前爲止的代碼:

func shortNameFromName(name: String) -> String { 
    var shortName = name.lowercased() 
    let vowels = "aeiou" 
    let vowelRange = CharacterSet(charactersIn: vowels) 
    rangeOfCharacter(from: vowels, options: shortName, 
       range: substring(from: shortName[0])) 

任何幫助深表感謝。爲新手的錯誤道歉。

+0

你正在得到什麼輸出 – Tech

回答

2

使用此代碼使用正則表達式你的問題就解決了

改進

func shortNameFromName(name: String) -> String { 
    do{ 
     let regex2 = try NSRegularExpression(pattern: "[a|e|i|o|u].*", options:[.dotMatchesLineSeparators]) 
     if let result = regex2.firstMatch(in: name.lowercased(), options: .init(rawValue: 0), range: NSRange(location: 0, length: NSString(string: name).length)) 
     { 
      return String(NSString(string: name).substring(with: result.range)) 
     } 
    } 
    catch 
    { 
     debugPrint(error.localizedDescription) 
    } 
    return "" 
} 

測試

debugPrint(self.shortNameFromName(name: "yhcasid")) //test1 
debugPrint(self.shortNameFromName(name: "ayhcasid")) //test2 
debugPrint(self.shortNameFromName(name: "abc")) // working thanks to @MartinR 

控制檯登錄

TEST1結果

「ASID」

TEST2導致

「ayhcasid」

TEST3導致

「ABC」

希望這有助於

+0

我比那些使用非直觀的Swift範圍的人更喜歡這個答案。另一方面,我不喜歡你使用Objective-C'NSString'對象。 –

+0

@MichaelDautermann是爲了避免swift的NSRange問​​題 –

+0

Try'shortNameFromName(name:「abc」)'......你看到問題了嗎? –

1

我恨斯威夫特範圍。但希望事情會更好用Swift 4.

let name = "Michael" 
var shortName = name.lowercased() 
let vowels = "aeiou" 
let vowelSet = CharacterSet(charactersIn: vowels) 

let stringSet = shortName 
if let range = stringSet.rangeOfCharacter(from: vowelSet, options: String.CompareOptions.caseInsensitive) 
{ 
    let startIndex = range.lowerBound 

    let substring = name.substring(from: range.lowerBound) 
    print(substring) 
} 
1

您正在向該方法傳遞完全錯誤的參數。

rangeOfCharacter接受3個參數。您正確傳遞了字符集,但您傳遞的最後兩個參數沒有意義。你應該傳遞一堆選項作爲第二個參數,而不是傳入一個字符串。第三個參數應該是Range,但您傳遞的是substring調用的返回值。我覺得rangeOfCharacter這裏不適合。有很多更好的方法來做到這一點。例如:

func shortNameFromName(name: String) -> String { 
    return String(name.characters.drop(while: {!"aeiou".characters.contains($0)})) 
} 
+1

您可能想要編輯這個:'String.characterView'沒有名爲'drop'的成員/函數。 –

+0

@MichaelDautermann我在操場上試了這個,它編譯併產生了預期的結果。 'drop'在'Collection'中聲明,'CharacterView'符合,對吧?還是你沒有使用Swift 3? – Sweeper

+0

我正在使用Xcode 8.2和一個操場,我的自動完成向角色展示'dropFirst'和'dropLast',但沒有'drop'。呵呵,如果你說它對你有用,也許它適用於OP –

0

斯威夫特3 這裏更換您的代碼..

func shortNameFromName(name: String) -> String { 
var shortName = name.lowercased() 
let newstring = shortName 
let vowels: [Character] = ["a","e","i","o","u"] 
for i in shortName.lowercased().characters { 
    if vowels.contains(i) { 
     break 
    } 
    else { 
     shortName = shortName.replacingOccurrences(of: "\(i)", with: "") 
    } 

} 

if shortName != "" { 
    return shortName 
} 
else 
{ 
    return newstring 
}