如何使用swift 2.0获取lastIndexof

时间:2015-09-27 20:02:20

标签: swift

我试图实现一个方法lastIndexOf。我的代码

extension String {
    var length:Int {
        return self.characters.count
    }

    func indexOf(target: String) -> Int? {

        let range = (self as NSString).rangeOfString(target)

        guard range.toRange() != nil else {
            return nil
        }

        return range.location

    }
    func lastIndexOf(target: String) -> Int? {

        let range = (self as NSString).rangeOfString(target, options: NSStringCompareOptions.BackwardsSearch)

        guard range.toRange() != nil else {
            return nil
        }

        return self.length - range.location - 1

    }
}

IndexOf让我回归45

“11055010155031e146145257690278f95004eca3d9ea110038da71507” .indexOf( “1003”)

但是lastIndexOf 11

“11055010155031e146145257690278f95004eca3d9ea110038da71507” .lastIndexOf( “1003”)

我不确定我的错误在哪里

感谢您的帮助

1 个答案:

答案 0 :(得分:14)

您的lastIndexOf()方法返回11,因为

return self.length - range.location - 1

计算找到子字符串的位置的偏移量 在你的情况57 - 45 - 1 = 11中,到字符串的最后一个字符。 如果将return语句更改为

return range.location

然后你会得到45这两个调用,因为子字符串“1003” 只在较大的字符串中出现一次。

请注意,您可以在不使用NSString / NSRange的情况下计算偏移量:

extension String {
    func indexOf(target: String) -> Int? {
        if let range = self.rangeOfString(target) {
            return startIndex.distanceTo(range.startIndex)
        } else {
            return nil
        }
    }

    func lastIndexOf(target: String) -> Int? {
        if let range = self.rangeOfString(target, options: .BackwardsSearch) {
            return startIndex.distanceTo(range.startIndex)
        } else {
            return nil
        }
    }
}

对于字符外的字符串,这也更有效 “基本多语言平面”,如表情符号或“旗帜”。例子是

"abcdef".indexOf("d")

您的方法返回5而不是4

"abcdef".indexOf("d")

您的方法返回7而不是4

Swift 3的更新:

extension String {
    func index(of target: String) -> Int? {
        if let range = self.range(of: target) {
            return characters.distance(from: startIndex, to: range.lowerBound)
        } else {
            return nil
        }
    }

    func lastIndex(of target: String) -> Int? {
        if let range = self.range(of: target, options: .backwards) {
            return characters.distance(from: startIndex, to: range.lowerBound)
        } else {
            return nil
        }
    }
}