它通常有助于将问题分解为多个功能。在这里,你需要做两件事 - 处理字符串,提取数字和可能的额外信息。然后,遍历字符串数组,直到找到合适的条目。
首先进行字符串处理。给定一个字符串,你想返回一对(阅读和额外的信息),或“未找到”。无论何时您需要返回或找不到,可选是一个不错的选择。所以,你想一个函数接受一个字符串,并返回一个可选(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