var LabelAQI = "-"
var LabelExtraInfo = "-"
var arrAQI = [NSString]()
var AQI1:NSString = "55a"
var AQI2:NSString = "95a"
var AQI3:NSString = "66"
var AQI4:NSString = "25"
var AQI5:NSString = "88b"
var AQI6:NSString = "#"
arrAQI[0...5] = [AQI1, AQI2, AQI3, AQI4, AQI5, AQI6]使用Swift,我从一个以NSString形式的网站获取空气质量指数( AQI )数据。AQI1 to AQI6本质上是每小时的AQI数据(例如,从上午12点到凌晨5点,我在实际代码中已经达到AQI24了)。"#“表示尚未获得数据。整数是AQI,有时可能有"a"/"b“表示的额外信息与整数相关,即”一氧化碳存在“/”二氧化硫存在“。我想做的是:
1)在arrAQI上显示最后一个整数(不包括"#",也不显示"a"/"b",即"88")。
2)在LabelExtraInfo上显示“一氧化碳存在”/“二氧化硫存在”,如果有"a"/"b“,最后一个整数来自arrAQI,如果没有,请离开LabelExtraInfo.text = "-”。
我才几周就开始编程了。有人能帮忙吗?有没有更好的方法来做我想做的事?提前谢谢你。
发布于 2015-05-17 14:34:20
这可以通过将字符串爆炸成对象数组来完成,然后检查每个对象:
var LabelAQI = "-"
var LabelExtraInfo = "-"
var stringFromServer = "55a 95a 66 25 88b #"
var objectsSeparated = stringFromServer.componentsSeparatedByString(" ")
for object in objectsSeparated
{
if object.hasSuffix("a")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "Carbon Monoxide present"
}
else if object.hasSuffix("b")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "Sulphur Dioxide present"
}
else if object.hasSuffix("#")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "-"
}
else
{
LabelAQI = object
LabelExtraInfo = "-"
}
}更新
要找到最后一个没有“#”后缀的对象,可以使用以下代码:
var LabelAQI = "-"
var LabelExtraInfo = "-"
var stringFromServer = "55a 95a 66 25 88b #"
var objectsSeparated = stringFromServer.componentsSeparatedByString(" ")
var index = objectsSeparated.count
while 0 >= index
{
var object = objectsSeparated[index]
index--
if object.hasSuffix("#")
{
//this object has '#' suffix -> skip it
continue
}
else
{
//found non '#' object
if object.hasSuffix("a")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "Carbon Monoxide present"
}
else if object.hasSuffix("b")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "Sulphur Dioxide present"
}
else
{
LabelAQI = object
LabelExtraInfo = "-"
}
break
}
}发布于 2015-05-17 11:41:00
它通常有助于将问题分解为多个函数。在这里,您需要做两件事-处理字符串,提取一个数字和可能的额外信息。然后,循环遍历字符串数组,直到找到合适的条目为止。
首先是字符串处理。给定一个字符串,您希望返回一对(读取和额外信息)或“未找到”。无论何时您需要返回某个东西或没有找到,可选选项是一个很好的选择。因此,您需要一个接受字符串并返回可选(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
}顺便提一下,其他一些Swift技巧:通常使用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,]发布于 2015-05-17 11:00:54
有很多方法可以做到这一点,下面有一个使用NSScanner的建议:
var LabelAQI = "-"
var LabelExtraInfo = "-"
var arrAQI = [NSString]()
let AQI1:NSString = "55a", AQI2 = "95a", AQI3 = "66", AQI4 = "25", AQI5 = "88b", AQI6 = "#"
arrAQI.extend([AQI1, AQI2, AQI3, AQI4, AQI5, AQI6])
for AQI in reverse(arrAQI) {
if AQI != "#" {
var str:NSString?
let numberSet = NSCharacterSet.decimalDigitCharacterSet()
let letterSet = NSCharacterSet(charactersInString: "ab")
let scanner = NSScanner(string: AQI as String)
if scanner.scanCharactersFromSet(numberSet, intoString:&str) {
LabelAQI = str as! String
if scanner.scanCharactersFromSet(letterSet, intoString: &str) {
switch str as! String {
case "a":
LabelExtraInfo = "Carbon Monoxide present"
case "b":
LabelExtraInfo = "Sulphur Dioxide present"
default:
break
}
}
break
}
}
}
LabelAQI // "88"
LabelExtraInfo // "Sulphur Dioxide present"首先,我反转数组并循环遍历它,以获得最后一个非哈希符号条目。然后,使用NSCharacterSet搜索,首先扫描字符串以获取数字,然后扫描字母a/b。一旦发现,我们就可以跳出循环,一切都完成了。
注意:这行代码arrAQI[0...5] = [AQI1, AQI2, AQI3, AQI4, AQI5, AQI6]没有工作,所以我用arrAQI.extend([AQI1, AQI2, AQI3, AQI4, AQI5, AQI6])替换了它。
https://stackoverflow.com/questions/30284702
复制相似问题