它通常有助於將問題分解爲多個功能。在這裏,你需要做兩件事 - 處理字符串,提取數字和可能的額外信息。然後,遍歷字符串數組,直到找到合適的條目。
首先進行字符串處理。給定一個字符串,你想返回一對(閱讀和額外的信息),或「未找到」。無論何時您需要返回或找不到,可選是一個不錯的選擇。所以,你想一個函數接受一個字符串,並返回一個可選(Int,String)
對:
func extractData(input: String) -> (Int,String)?
但是你可以走一步,定義一個枚舉來表示的額外信息的不同位:
enum AirQualityInfo {
case CarbonMonoxide,
SulphurDioxide,
NoInfo
}
func extractData(input: String) -> (Int,AirQualityInfo)?
這樣,所有你討厭的字符串處理都包含在extractData
之內。
在這個函數中,你想檢查一個已知的尾隨字符,然後去掉它,如果剩下的是一個數字,返回這兩個值。但是,如果仍然不是一個數字,返回nil
:
func extractData(input: String) -> (Int,AirQualityInfo)? {
let stripped: String
let extraInfo: AirQualityInfo
switch last(input) {
case .Some("a"):
stripped = dropLast(input)
extraInfo = .CarbonMonoxide
case .Some("b"):
stripped = dropLast(input)
extraInfo = .SulphurDioxide
default:
stripped = input
extraInfo = .NoInfo
}
return stripped.toInt().map { ($0,extraInfo) }
}
你可以,如其他人所說,使用這種正則表達式,但我個人認爲這是矯枉過正給您的數據分析需求是如此具體。
一旦你有了這個功能,可以循環以相反的順序排列,使用功能,直到找到一個有效的值檢查每個價值過:
for idx in reverse(indices(arrAQI)) {
if let (index, extraInfo) = extractData(arrAQI[idx]) {
LabelAQI = toString(index)
switch extraInfo {
case .CarbonMonoxide:
LabelExtraInfo = "Carbon Monoxide Present"
case .SulphurDioxide:
LabelExtraInfo = "SulphurDioxide Present"
case .NoInfo:
LabelExtraInfo = "-"
}
// stop going around the loop
break
}
}
你也分解出的是轉換串了進一步的還有:
extension AirQualityInfo {
var displayString: String {
switch self {
case .CarbonMonoxide:
return "Carbon Monoxide Present"
case .SulphurDioxide:
return "SulphurDioxide Present"
case .NoInfo:
return "-"
}
}
}
for idx in reverse(indices(arrAQI)) {
if let (index, extraInfo) = extractData(arrAQI[idx]) {
LabelAQI = toString(index)
LabelExtraInfo = extraInfo.displayString
break
}
}
最後,如果你覺得超級冒險,你可以寫,做一個函數,一次性發現和映射操作:
func findSome<C: CollectionType, T>
(source: C, match: C.Generator.Element -> T?)
-> T? {
for element in source {
if let x = match(element) {
return x
}
}
return nil
}
if let (index, extraInfo) = findSome(reverse(arrAQI),extractData) {
LabelAQI = toString(index)
LabelExtraInfo = extraInfo.displayString
}
順便說一句,其他一些斯威夫特提示:這是一般最好使用String
而非NSString
,除非你對某事物的具體需求是一個NSString
(它看起來並不像這裏);在聲明它們時不需要命名這些類型 - 您可以編寫let str = "hello"
而不是let str: String = "hello"
,這往往會使代碼看起來更簡潔,更易於閱讀;並且,最好在後面的代碼使用let
而不是var
,除非你明確地需要改變(「變異」)值...所以鑑於這一切,這裏是如何,你可以宣佈你原來的數組:
let AQI1 = "55a"
let AQI2 = "95a"
let AQI3 = "66"
let AQI4 = "25"
let AQI5 = "88b"
let AQI6 = "#"
let arrAQI = [AQI1,AQI2,AQI3,AQI4,AQI5,AQI6,]
考慮使用正則表達式 http://www.raywenderlich.com/86205/nsregularexpression-swift-tutorial – boidkan