Split String into groups with specific length

后端 未结 10 1774
囚心锁ツ
囚心锁ツ 2021-01-05 09:32

How can I split the given String in Swift into groups with given length, reading from right to left?

For example, I have string 123456789 a

相关标签:
10条回答
  • 2021-01-05 10:18

    Swift 4

    I adapted the answer given by cafedeichi to operate either left-to-right or right-to-left depending on a function parameter, so it's more versatile.

    extension String {
        /// Splits a string into groups of `every` n characters, grouping from left-to-right by default. If `backwards` is true, right-to-left.
        public func split(every: Int, backwards: Bool = false) -> [String] {
            var result = [String]()
    
            for i in stride(from: 0, to: self.count, by: every) {
                switch backwards {
                case true:
                    let endIndex = self.index(self.endIndex, offsetBy: -i)
                    let startIndex = self.index(endIndex, offsetBy: -every, limitedBy: self.startIndex) ?? self.startIndex
                    result.insert(String(self[startIndex..<endIndex]), at: 0)
                case false:
                    let startIndex = self.index(self.startIndex, offsetBy: i)
                    let endIndex = self.index(startIndex, offsetBy: every, limitedBy: self.endIndex) ?? self.endIndex
                    result.append(String(self[startIndex..<endIndex]))
                }
            }
    
            return result
        }
    }
    

    Example:

    "abcde".split(every: 2)                     // ["ab", "cd", "e"]
    "abcde".split(every: 2, backwards: true)    // ["a", "bc", "de"]
    
    "abcde".split(every: 4)                     // ["abcd", "e"]
    "abcde".split(every: 4, backwards: true)    // ["a", "bcde"]
    
    0 讨论(0)
  • 2021-01-05 10:19

    Swift 4

    I think the extension method is more useful.

    extension String{
    
        public func splitedBy(length: Int) -> [String] {
    
            var result = [String]()
    
            for i in stride(from: 0, to: self.characters.count, by: length) {
                let endIndex = self.index(self.endIndex, offsetBy: -i)
                let startIndex = self.index(endIndex, offsetBy: -length, limitedBy: self.startIndex) ?? self.startIndex
                result.append(String(self[startIndex..<endIndex]))
            }
    
            return result.reversed()
    
        }
    
    }
    

    the example of use:

    Swift.debugPrint("123456789".splitedBy(length: 4))
    // Returned ["1", "2345", "6789"]
    
    0 讨论(0)
  • 2021-01-05 10:23

    Here is a version using NSRegularExpressions

    func splitedString(string: String, length: Int) -> [String] {
        var groups = [String]()
        let regexString = "(\\d{1,\(length)})"
        do {
            let regex = try NSRegularExpression(pattern: regexString, options: .CaseInsensitive)
            let matches = regex.matchesInString(string, options: .ReportCompletion, range: NSMakeRange(0, string.characters.count))
            let nsstring = string as NSString
            matches.forEach {
                let group = nsstring.substringWithRange($0.range) as String
                groups.append(group)
            }
        } catch let error as NSError {
            print("Bad Regex Format = \(error)")
        }
    
        return groups
    }
    
    0 讨论(0)
  • 2021-01-05 10:26

    This is what I came up with off the top of my head. I bet there is a better way of doing it so I'd encourage you to keep trying.

    func splitedString(string: String, length: Int) -> [String] {
        var groups = [String]()
        var currentGroup = ""
        for index in string.startIndex..<string.endIndex {
            currentGroup.append(string[index])
            if currentGroup.characters.count == 3 {
                groups.append(currentGroup)
                currentGroup = ""
            }
        }
    
        if currentGroup.characters.count > 0 {
            groups.append(currentGroup)
        }
    
        return groups
    }
    

    Here were my tests

    let firstString = "123456789"
    let groups = splitedString(firstString, length: 3)
    // Returned ["123", "456", "789"]
    
    let secondString = "1234567"
    let moreGroups = splitedString(secondString, length: 3)
    // Returned ["123", "456", "7"]
    
    0 讨论(0)
提交回复
热议问题