首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift:如何从NSString数组中获取最后一个整数?

Swift:如何从NSString数组中获取最后一个整数?
EN

Stack Overflow用户
提问于 2015-05-17 08:05:30
回答 4查看 306关注 0票数 2
代码语言:javascript
复制
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 = "-”。

我才几周就开始编程了。有人能帮忙吗?有没有更好的方法来做我想做的事?提前谢谢你。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-05-17 14:34:20

这可以通过将字符串爆炸成对象数组来完成,然后检查每个对象:

代码语言:javascript
复制
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 = "-"
    }
}

更新

要找到最后一个没有“#”后缀的对象,可以使用以下代码:

代码语言:javascript
复制
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
    }
}
票数 1
EN

Stack Overflow用户

发布于 2015-05-17 11:41:00

它通常有助于将问题分解为多个函数。在这里,您需要做两件事-处理字符串,提取一个数字和可能的额外信息。然后,循环遍历字符串数组,直到找到合适的条目为止。

首先是字符串处理。给定一个字符串,您希望返回一对(读取和额外信息)或“未找到”。无论何时您需要返回某个东西或没有找到,可选选项是一个很好的选择。因此,您需要一个接受字符串并返回可选(Int,String)对的函数:

代码语言:javascript
复制
func extractData(input: String) -> (Int,String)?

但是,您可以更进一步,定义一个枚举来表示不同的额外信息:

代码语言:javascript
复制
enum AirQualityInfo {
    case CarbonMonoxide,
         SulphurDioxide,
         NoInfo
}

func extractData(input: String) -> (Int,AirQualityInfo)?

这样,所有讨厌的字符串处理都包含在extractData中。

在该函数中,您需要检查一个已知的尾随字符,然后去掉它,如果剩下的是一个数字,则返回这两个值。但是如果剩下的不是一个数字,返回nil

代码语言:javascript
复制
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) }
}

您可以,正如其他人所建议的那样,为此使用正则表达式,但我个人认为这是过分的,因为您的数据解析需求是如此具体。

拥有此函数后,可以按反向顺序遍历数组,使用该函数检查每个值,直到找到一个有效值为止:

代码语言:javascript
复制
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
    }
}

您还可以进一步推断字符串的转换:

代码语言:javascript
复制
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
    }
}

最后,如果您感到超级冒险,您可以编写一个函数,它可以一次性完成查找和映射操作:

代码语言:javascript
复制
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,除非明确需要在代码…中更改(“变异”)后面的值。因此,考虑到这些,下面是如何声明原始数组的方法:

代码语言:javascript
复制
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,]
票数 2
EN

Stack Overflow用户

发布于 2015-05-17 11:00:54

有很多方法可以做到这一点,下面有一个使用NSScanner的建议:

代码语言:javascript
复制
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])替换了它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30284702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档