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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.