0

Swift newbie here. I am trying to convert some of my python code to swift and im stuck at the point where I need to split a string of letters into and array with each item being 3 letters:

For example my python code is as follows:

name = "ATAGASSTSSGASTA"
threes =[]
for start in range(0, len(name),3):
   threes.append(name[start : start + 3])
print threes

For swift ive come as far as this:

var name = "ATAGASSTSSGASTA"
let namearr = Array(name)
let threes = []
threes.append(namearr[0...3])

This gives me an error.

I realize there may be an much easier way to do this, but I have not been able to find anything in my research. Any help is appreciated!

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
Ahk86
  • 177
  • 2
  • 11
  • This might help: http://stackoverflow.com/a/28560013/1187415. Here is a more generic approach: http://stackoverflow.com/a/26691258/1187415. – Martin R Mar 27 '15 at 17:06
  • `split=lambda s,n:[s[i:i+n] for i in range(0,len(s),n)]` ... `threes=split('ATAGASSTSSGASTA',3)` – Mr. Polywhirl Mar 27 '15 at 17:19

3 Answers3

3

An easy and Swifty way to do this is to map an array of chars using the stride and advance functions:

let name = Array("ATAGASSTSSGASTA")

let splitName = map(stride(from: 0, to: name.count, by: 3)) {
    String(name[$0..<advance($0, 3, name.count)])
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
Ian
  • 12,538
  • 5
  • 43
  • 62
  • 1
    It may or may not be relevant, but this gives an array of `Slice`, not an array of `String`. (That's why I used substringWithRange in http://stackoverflow.com/a/28560013/1187415) – Martin R Mar 27 '15 at 17:23
  • 1
    If OP is interested in a String array, you can generate a string from each `Slice` during the mapping. `String(name[$0.. – Mick MacCallum Mar 27 '15 at 17:27
  • For my case this was very relevant. I am going to us substringWithRange as i need the array of strings. Thank you to all of your answers! much appreciated!!! – Ahk86 Mar 27 '15 at 17:43
0

This is pretty verbose, but it does the job:

let name = "ATAGASSTSSGASTA"

let array = reduce(name, [String]()) {
    switch $0.last {
    case .Some(let last) where countElements(last) < 3:
        var array = $0
        array[array.endIndex-1].append($1)
        return array
    case .Some(_), .None:
        return $0 + [String($1)]
    }
}

Edit: In Swift 1.2, I think countElements has changed to just count. Not sure, don't have it yet, but the documents make it look that way.

Aaron Rasmussen
  • 13,082
  • 3
  • 42
  • 43
0
var nucString = "aatttatatatattgctgatctgatctEOS"
let nucArrayChar = Array(nucString)
var nucArray: [String] = []
var counter: Int = nucArrayChar.count

if counter % 3 == 0 {
    for var startNo = 0; startNo < counter; startNo += 3 {
    println("\(nucArray)\(startNo)")
    nucArray.append(String(nucArrayChar[(startNo)...(startNo + 2)]))
    }
}
lee
  • 1
  • 2