Search code examples
iosswiftnsstringswift4nsarray

How can split from string to array by chunks of given size


I want to split string by chunks of given size 2

Example :

String "1234567" and output should be ["12", "34", "56","7"]


Solution

  • You can group your collection elements (in this case Characters) every n elements as follow:

    extension Collection {
        func unfoldSubSequences(limitedTo maxLength: Int) -> UnfoldSequence<SubSequence,Index> {
            sequence(state: startIndex) { start in
                guard start < self.endIndex else { return nil }
                let end = self.index(start, offsetBy: maxLength, limitedBy: self.endIndex) ?? self.endIndex
                defer { start = end }
                return self[start..<end]
            }
        }
        func subSequences(of n: Int) -> [SubSequence] {
            .init(unfoldSubSequences(limitedTo: n))
        }
    }
    

    let numbers = "1234567"
    let subSequences = numbers.subSequences(of: 2)
    print(subSequences)    // ["12", "34", "56", "7"]
    

    edit/update:

    If you would like to append the exceeding characters to the last group:

    extension Collection {
        func unfoldSubSequencesWithTail(lenght: Int) -> UnfoldSequence<SubSequence,Index> {
            let n = count / lenght
            var counter = 0
            return sequence(state: startIndex) { start in
                guard start < endIndex else { return nil }
                let end = index(start, offsetBy: lenght, limitedBy: endIndex) ?? endIndex
                counter += 1
                if counter == n {
                    defer { start = endIndex }
                    return self[start...]
                } else {
                    defer { start = end }
                    return self[start..<end]
                }
            }
        }
        func subSequencesWithTail(n: Int) -> [SubSequence] {
            .init(unfoldSubSequencesWithTail(lenght: n))
        }
    }
    

    let numbers = "1234567"
    let subSequencesWithTail = numbers.subSequencesWithTail(n: 2)
    print(subSequencesWithTail)    // ["12", "34", "567"]