0

I have a string in Swift that looks like this:

["174580798","151240033","69753978","122754394","72373738","183135789","178841809","84104360","122823486","184553211","182415131","70707972"]

I need to convert it into an NSArray.

I've looked at other methods on SO but it is breaking each character into a separate array element, as opposed to breaking on the comma. See: Convert Swift string to array

I've tried to use the map() function, I've also tried various types of casting but nothing seems to come close.

Thanks in advance.

5
  • Is your string "174580798","151240033". I mean comma separated string? Commented Aug 22, 2015 at 11:11
  • yes (with square brakets on front and end) :) Commented Aug 22, 2015 at 11:13
  • Then it is already an Array. Commented Aug 22, 2015 at 11:14
  • It looks like one, but it is of string type and cannot be casted. Commented Aug 22, 2015 at 11:15
  • Have you tried componentsSeparatedByString function? Commented Aug 22, 2015 at 11:20

4 Answers 4

5

It's probably a JSON string so you can try this

let string = "[\"174580798\",\"151240033\",\"69753978\",\"122754394\",\"72373738\",\"183135789\",\"178841809\",\"84104360\",\"122823486\",\"184553211\",\"182415131\",\"70707972\"]"
let data = string.dataUsingEncoding(NSUTF8StringEncoding)!
let jsonArray = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(), error: nil) as! [String]

as the type [String] is distinct you can cast it forced

Swift 3+:

let data = Data(string.utf8)
let jsonArray = try! JSONSerialization.jsonObject(with: data) as! [String]
Sign up to request clarification or add additional context in comments.

1 Comment

This really should be the accepted answer. The original string is obviously JSON and this is how you parse JSON.
2

The other two answers are working, although SwiftStudiers isn't the best regarding performance. vadian is right that your string most likely is JSON. Here I present another method which doesn't involve JSON parsing and one which is very fast:

import Foundation

let myString = "[\"174580798\",\"151240033\",\"69753978\",\"122754394\",\"72373738\",\"183135789\",\"178841809\",\"84104360\",\"122823486\",\"184553211\",\"182415131\",\"70707972\"]"

func toArray(var string: String) -> [String] {
    string.removeRange(string.startIndex ..< advance(string.startIndex, 2)) // Remove first 2 chars
    string.removeRange(advance(string.endIndex, -2) ..< string.endIndex)    // Remote last 2 chars
    return string.componentsSeparatedByString("\",\"")
}

toArray(myString)    // ["174580798", "151240033", "69753978", ...

You probably want the numbers though, you can do this in Swift 2.0:

toArray(myString).flatMap{ Int($0) }    // [174'580'798, 151'240'033, 69'753'978, ...

which returns an array of Ints

EDIT: For the ones loving immutability and functional programming, have this solution:

func toArray(string: String) -> [String] {
    return string[advance(string.startIndex, 2) ..< advance(string.endIndex, -2)]
        .componentsSeparatedByString("\",\"")
}

or this:

func toArray(string: String) -> [Int] {
    return string[advance(string.startIndex, 2) ..< advance(string.endIndex, -2)]
        .componentsSeparatedByString("\",\"")
        .flatMap{ Int($0) }
}

Comments

1

Try this. I've just added my function which deletes any symbols from string except numbers. It helps to delete " and [] in your case

var myString = "[\"174580798\",\"151240033\",\"69753978\",\"122754394\",\"72373738\",\"183135789\",\"178841809\",\"84104360\",\"122823486\",\"184553211\",\"182415131\",\"70707972\"]"


        var s=myString.componentsSeparatedByString("\",\"")

        var someArray: [String] = []

        for i in s {
            someArray.append(deleteAllExceptNumbers(i))
        }
        println(someArray[0]);


func deleteAllExceptNumbers(str:String) -> String {
        var rez=""
        let digits = NSCharacterSet.decimalDigitCharacterSet()
        for tempChar in str.unicodeScalars {
            if digits.longCharacterIsMember(tempChar.value) {
                rez += tempChar.description
            }
        }
        return rez.stringByReplacingOccurrencesOfString("\u{22}", withString: "")
    }

3 Comments

But you did not come and post rich in perfomance answer, so you can leave your opinion to yourself
A few things to your code: Your function deleteAllExceptNumbers actually only does something to the first and last element; It creates an NSCharacterSet every time; it creates a new string every time even though 99% of the time the passed in string doesn't change at all, appending isn't cheap; why are you using \u{22} and not just \"?; your someArray has to allocate memory a lot of the time due to the appends; the original string gets walked through at least 3 times... Sorry to complain so much, but this just isn't very good code..
I'l take it into consideration, thanks. Think my nick will be explainful
1

Swift 1.2:

If as has been suggested you are wanting to return an array of Int you can get to that from myString with this single concise line:

var myArrayOfInt2 = myString.componentsSeparatedByString("\"").map{$0.toInt()}.filter{$0 != nil}.map{$0!}

In Swift 2 (Xcode 7.0 beta 5):

var myArrayOfInt = myString.componentsSeparatedByString("\"").map{Int($0)}.filter{$0 != nil}.map{$0!}

This works because the cast returns an optional which will be nil where the cast fails - e.g. with [, ] and ,. There seems therefore to be no need for other code to remove these characters.

EDIT: And as Kametrixom has commented below - this can be further simplified in Swift 2 using .flatMap as follows:

var myArrayOfInt = myString.componentsSeparatedByString("\"").flatMap{ Int($0) }

Also - and separately:

With reference to Vadian's excellent answer. In Swift 2 this will become:

// ...

do {
    let jsonArray = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as! [String]
} catch {
    _ = error // or do something with the error
} 

2 Comments

You can use flatMap{ Int($0) } instead of map{Int($0)}.filter{$0 != nil}.map{$0!}
Excellent - I have added that solution to my answer. I really like how concise this is.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.