How to create range in Swift?

前端 未结 10 1471
时光说笑
时光说笑 2020-11-28 01:37

In Objective-c we create range by using NSRange

NSRange range;

So how to create range in Swift?

相关标签:
10条回答
  • 2020-11-28 02:04

    Updated for Swift 4

    Swift ranges are more complex than NSRange, and they didn't get any easier in Swift 3. If you want to try to understand the reasoning behind some of this complexity, read this and this. I'll just show you how to create them and when you might use them.

    Closed Ranges: a...b

    This range operator creates a Swift range which includes both element a and element b, even if b is the maximum possible value for a type (like Int.max). There are two different types of closed ranges: ClosedRange and CountableClosedRange.

    1. ClosedRange

    The elements of all ranges in Swift are comparable (ie, they conform to the Comparable protocol). That allows you to access the elements in the range from a collection. Here is an example:

    let myRange: ClosedRange = 1...3
    
    let myArray = ["a", "b", "c", "d", "e"]
    myArray[myRange] // ["b", "c", "d"]
    

    However, a ClosedRange is not countable (ie, it does not conform to the Sequence protocol). That means you can't iterate over the elements with a for loop. For that you need the CountableClosedRange.

    2. CountableClosedRange

    This is similar to the last one except now the range can also be iterated over.

    let myRange: CountableClosedRange = 1...3
    
    let myArray = ["a", "b", "c", "d", "e"]
    myArray[myRange] // ["b", "c", "d"]
    
    for index in myRange {
        print(myArray[index])
    }
    

    Half-Open Ranges: a..<b

    This range operator includes element a but not element b. Like above, there are two different types of half-open ranges: Range and CountableRange.

    1. Range

    As with ClosedRange, you can access the elements of a collection with a Range. Example:

    let myRange: Range = 1..<3
    
    let myArray = ["a", "b", "c", "d", "e"]
    myArray[myRange] // ["b", "c"]
    

    Again, though, you cannot iterate over a Range because it is only comparable, not stridable.

    2. CountableRange

    A CountableRange allows iteration.

    let myRange: CountableRange = 1..<3
    
    let myArray = ["a", "b", "c", "d", "e"]
    myArray[myRange] // ["b", "c"]
    
    for index in myRange {
        print(myArray[index])
    }
    

    NSRange

    You can (must) still use NSRange at times in Swift (when making attributed strings, for example), so it is helpful to know how to make one.

    let myNSRange = NSRange(location: 3, length: 2)
    

    Note that this is location and length, not start index and end index. The example here is similar in meaning to the Swift range 3..<5. However, since the types are different, they are not interchangeable.

    Ranges with Strings

    The ... and ..< range operators are a shorthand way of creating ranges. For example:

    let myRange = 1..<3
    

    The long hand way to create the same range would be

    let myRange = CountableRange<Int>(uncheckedBounds: (lower: 1, upper: 3)) // 1..<3
    

    You can see that the index type here is Int. That doesn't work for String, though, because Strings are made of Characters and not all characters are the same size. (Read this for more info.) An emoji like

    0 讨论(0)
  • 2020-11-28 02:06

    I created the following extension:

    extension String {
        func substring(from from:Int, to:Int) -> String? {
            if from<to && from>=0 && to<self.characters.count {
                let rng = self.startIndex.advancedBy(from)..<self.startIndex.advancedBy(to)
                return self.substringWithRange(rng)
            } else {
                return nil
            }
        }
    }
    

    example of use:

    print("abcde".substring(from: 1, to: 10)) //nil
    print("abcde".substring(from: 2, to: 4))  //Optional("cd")
    print("abcde".substring(from: 1, to: 0))  //nil
    print("abcde".substring(from: 1, to: 1))  //nil
    print("abcde".substring(from: -1, to: 1)) //nil
    
    0 讨论(0)
  • 2020-11-28 02:14

    If anyone want to create NSRange object can create as:

    let range: NSRange = NSRange.init(location: 0, length: 5)
    

    this will create range with position 0 and length 5

    0 讨论(0)
  • 2020-11-28 02:22
    func replace(input: String, start: Int,lenght: Int, newChar: Character) -> String {
        var chars = Array(input.characters)
    
        for i in start...lenght {
            guard i < input.characters.count else{
                break
            }
            chars[i] = newChar
        }
        return String(chars)
    }
    
    0 讨论(0)
  • 2020-11-28 02:25

    Use like this

    var start = str.startIndex // Start at the string's start index
    var end = advance(str.startIndex, 5) // Take start index and advance 5 characters forward
    var range: Range<String.Index> = Range<String.Index>(start: start,end: end)
    
    let firstFiveDigit =  str.substringWithRange(range)
    
    print(firstFiveDigit)
    

    Output : Hello

    0 讨论(0)
  • 2020-11-28 02:26

    I want to do this:

    print("Hello"[1...3])
    // out: Error
    

    But unfortunately, I can't write a subscript of my own because the loathed one takes up the name space.

    We can do this however:

    print("Hello"[range: 1...3])
    // out: ell 
    

    Just add this to your project:

    extension String {
        subscript(range: ClosedRange<Int>) -> String {
            get {
                let start = String.Index(utf16Offset: range.lowerBound, in: self)
                let end = String.Index(utf16Offset: range.upperBound, in: self)
                return String(self[start...end])
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题