1

I have a string of numbers (each number is separated by ,) that looks like this:

"12,3,5,75,584,364,57,88,94,4,79,333,7465,867,56,6,748,546,573,466"

I want to split the string to an array of strings, that each element is a string that has maximum 10 number in it.

For the example I've added I want to achieve something like this:

stringsArray:

Element 0: "12,3,5,75,584,364,57,88,94,4"
Element 1: "79,333,7465,867,56,6,748,546,573,466"

And so on...

I've been thinking a lot about a way to do this with Swift, but couldn't find anything...

Does anybody has an idea?

Thank you!

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
FS.O6
  • 1,394
  • 2
  • 20
  • 42
  • 1
    There's valuable method on NSString called componentsSeparatedByString: (https://developer.apple.com/documentation/foundation/nsstring/1413214-components). Use the resulting array to rebuild into strings with the corresponding componentsJoinedByString – danh Dec 25 '17 at 14:10
  • @danh Can you please explain a bit more? I'm using Swift (not Obj-C, so I'm using `String` and not `NSString`). Thank you – FS.O6 Dec 25 '17 at 14:14

2 Answers2

3

Step 1 - get fully separated array:

let numbers = "12,3,5".components(separatedBy: ",")

Step 2 - chunk your result to parts with ext:

extension Array {
    func chunked(by chunkSize: Int) -> [[Element]] {
        return stride(from: 0, to: self.count, by: chunkSize).map {
            Array(self[$0..<Swift.min($0 + chunkSize, self.count)])
        }
    }
}

let chunkedNumbers = numbers.chunked(by: 10)

Step 3:

let stringsArray = chunkedNumbers.map { $0.joined(separator: ",") }

Result: ["12,3,5,75,584,364,57,88,94,4", "79,333,7465,867,56,6,748,546,573,466"]

Link to gist playground.

biloshkurskyi.ss
  • 1,358
  • 3
  • 15
  • 34
  • Thank you, I've tried it. But the result isn't an array of strings that each one has the amount of numbers separated by `,` – FS.O6 Dec 25 '17 at 15:08
  • In your example the result is: `[["12", "3", "5", "75", "584", "364", "57", "88", "94", "4"], ["79", "333", "7465", "867", "56", "6", "748", "546", "573", "466"]] `. But I want it to be: `[["12,3,5,75,584,364,57,88,94,4"], ["79,333,7465,867,56,6,748,546,573,466"]]` – FS.O6 Dec 25 '17 at 15:21
  • @FS.O6 Look to step 3 – biloshkurskyi.ss Dec 25 '17 at 15:22
  • Please don't forget to add a link to the original source if you use code writte by others. The `chunked(by:)` extension has been posted before, e.g. here https://stackoverflow.com/a/38156873/1187415 and here https://stackoverflow.com/a/42638389/1187415 – Martin R Dec 25 '17 at 16:09
0

I would look at the position of 10th comma in your original string, get the prefix up to this position, remove this prefix and repeat until remaining string is empty.

This is a bit brute force, but works.

I first add extension to String for convenience.

extension String {

func startIndexesOf(_ string: String) -> [Int] {
    var result: [Int] = []
    var start = startIndex
    while let range = range(of: string, options: .literal, range: start..<endIndex) {
        result.append(range.lowerBound.encodedOffset)
        start = range.upperBound
    }
    return result
}

subscript (r: Range<Int>) -> String {
    let start = index(self.startIndex, offsetBy: r.lowerBound)
    let end = self.index(self.startIndex, offsetBy: r.upperBound)
    return String(self[Range(start ..< end)])
    }
}

let test = "12,3,5,75,584,364,57,88,94,4,79,333,7465,867,56,6,748,546,573,466,999"
var remaining = test
var arrayOf10 : [String] = []

repeat {
    let indexes = remaining.startIndexesOf(",")
    if indexes.count < 10 {
        arrayOf10.append(remaining) // Just add what remains
        break
   }

   let position = indexes[9]

   let endBeginning = remaining.index(test.startIndex, offsetBy: position)  // Beginning of what remain to parse
   let beginningSubstring = remaining[remaining.startIndex ..< endBeginning]
   let beginningText = String(beginningSubstring)
   arrayOf10.append(beginningText)

   let startNext = remaining.index(test.startIndex, offsetBy: position+1)  // What will remain to parse after taking out the beginning
   let remainingSubString = remaining[startNext ..< remaining.endIndex]
   remaining = String(remainingSubString)

} while remaining.count > 0

for (c, s) in arrayOf10.enumerated() { print("Element", c, ": ", s)}

This will print as desired

Element 0 :  12,3,5,75,584,364,57,88,94,4
Element 1 :  79,333,7465,867,56,6,748,546,573,466
Element 2 :  999
claude31
  • 874
  • 6
  • 8