I know how to programmatically do it, but I'm sure there's a built-in way...
Every language I've used has some sort of default textual representation for a collection of objects that it will spit out when you try to concatenate the Array with a string, or pass it to a print() function, etc. Does Apple's Swift language have a built-in way of easily turning an Array into a String, or do we always have to be explicit when stringifying an array?
If the array contains strings, you can use the String's join method:
var array = ["1", "2", "3"]
let stringRepresentation = "-".join(array) // "1-2-3"
In Swift 2:
var array = ["1", "2", "3"]
let stringRepresentation = array.joinWithSeparator("-") // "1-2-3"
This can be useful if you want to use a specific separator (hypen, blank, comma, etc).
Otherwise you can simply use the description property, which returns a string representation of the array:
let stringRepresentation = [1, 2, 3].description // "[1, 2, 3]"
Hint: any object implementing the Printable protocol has a description property. If you adopt that protocol in your own classes/structs, you make them print friendly as well
In Swift 3
join becomes joined, example [nil, "1", "2"].flatMap({$0}).joined()
joinWithSeparator becomes joined(separator:) (only available to Array of Strings)
In Swift 4
var array = ["1", "2", "3"]
array.joined(separator:"-")
With Swift 5, according to your needs, you may choose one of the following Playground sample codes in order to solve your problem.
Turning an array of Characters into a String with no separator:
let characterArray: [Character] = ["J", "o", "h", "n"]
let string = String(characterArray)
print(string)
// prints "John"
Turning an array of Strings into a String with no separator:
let stringArray = ["Bob", "Dan", "Bryan"]
let string = stringArray.joined(separator: "")
print(string) // prints: "BobDanBryan"
Turning an array of Strings into a String with a separator between words:
let stringArray = ["Bob", "Dan", "Bryan"]
let string = stringArray.joined(separator: " ")
print(string) // prints: "Bob Dan Bryan"
Turning an array of Strings into a String with a separator between characters:
let stringArray = ["car", "bike", "boat"]
let characterArray = stringArray.flatMap { $0 }
let stringArray2 = characterArray.map { String($0) }
let string = stringArray2.joined(separator: ", ")
print(string) // prints: "c, a, r, b, i, k, e, b, o, a, t"
Turning an array of Floats into a String with a separator between numbers:
let floatArray = [12, 14.6, 35]
let stringArray = floatArray.map { String($0) }
let string = stringArray.joined(separator: "-")
print(string)
// prints "12.0-14.6-35.0"
Swift 2.0 Xcode 7.0 beta 6 onwards uses joinWithSeparator() instead of join():
var array = ["1", "2", "3"]
let stringRepresentation = array.joinWithSeparator("-") // "1-2-3"
joinWithSeparator is defined as an extension on SequenceType
extension SequenceType where Generator.Element == String {
/// Interpose the `separator` between elements of `self`, then concatenate
/// the result. For example:
///
/// ["foo", "bar", "baz"].joinWithSeparator("-|-") // "foo-|-bar-|-baz"
#warn_unused_result
public func joinWithSeparator(separator: String) -> String
}
Swift 3
["I Love","Swift"].joined(separator:" ") // previously joinWithSeparator(" ")
Since no one has mentioned reduce, here it is:
[0, 1, 1, 0].map {"\($0)"}.reduce("") { $0 + $1 } // "0110"
In the spirit of functional programming ๐ค
In Swift 4
let array:[String] = ["Apple", "Pear ","Orange"]
array.joined(separator: " ")
To change an array of Optional/Non-Optional Strings
//Array of optional Strings
let array : [String?] = ["1",nil,"2","3","4"]
//Separator String
let separator = ","
//flatMap skips the nil values and then joined combines the non nil elements with the separator
let joinedString = array.flatMap{ $0 }.joined(separator: separator)
//Use Compact map in case of **Swift 4**
let joinedString = array.compactMap{ $0 }.joined(separator: separator
print(joinedString)
Here flatMap, compactMap skips the nil values in the array and appends the other values to give a joined string.
Nowadays, in iOS 13+ and macOS 10.15+, we might use ListFormatter:
let formatter = ListFormatter()
let names = ["Moe", "Larry", "Curly"]
if let string = formatter.string(from: names) {
print(string)
}
That will produce a nice, natural language string representation of the list. A US user will see:
Moe, Larry, and Curly
It will support any languages for which (a) your app has been localized; and (b) the userโs device is configured. For example, a German user with an app supporting German localization, would see:
Moe, Larry und Curly
Mine works on NSMutableArray with componentsJoinedByString
var array = ["1", "2", "3"]
let stringRepresentation = array.componentsJoinedByString("-") // "1-2-3"
In Swift 2.2 you may have to cast your array to NSArray to use componentsJoinedByString(",")
let stringWithCommas = (yourArray as NSArray).componentsJoinedByString(",")
let arrayTemp :[String] = ["Mani","Singh","iOS Developer"]
let stringAfterCombining = arrayTemp.componentsJoinedByString(" ")
print("Result will be >>> \(stringAfterCombining)")
Result will be >>> Mani Singh iOS Developer
If you want to ditch empty strings in the array.
["Jet", "Fire"].filter { !$0.isEmpty }.joined(separator: "-")
If you want to filter nil values as well:
["Jet", nil, "", "Fire"].flatMap { $0 }.filter { !$0.isEmpty }.joined(separator: "-")
you can use joined() to get a single String when you have array of struct also.
struct Person{
let name:String
let contact:String
}
You can easily produce string using map() & joined()
PersonList.map({"\($0.name) - \($0.contact)"}).joined(separator: " | ")
output:
Jhon - 123 | Mark - 456 | Ben - 789
if you want convert custom object array to string or comma separated string (csv) you can use
var stringIds = (self.mylist.map{$0.id ?? 0}).map{String($0)}.joined(separator: ",")
credit to : urvish modi
post: Convert an array of Ints to a comma separated string
A separator can be a bad idea for some languages like Hebrew or Japanese.
Try this:
// Array of Strings
let array: [String] = ["red", "green", "blue"]
let arrayAsString: String = array.description
let stringAsData = arrayAsString.data(using: String.Encoding.utf16)
let arrayBack: [String] = try! JSONDecoder().decode([String].self, from: stringAsData!)
For other data types respectively:
// Set of Doubles
let set: Set<Double> = [1, 2.0, 3]
let setAsString: String = set.description
let setStringAsData = setAsString.data(using: String.Encoding.utf16)
let setBack: Set<Double> = try! JSONDecoder().decode(Set<Double>.self, from: setStringAsData!)
You can either use loops for getting this done. Or by using map.
By mapping:
let array = ["one" , "two" , "three"]
array.map({$0}).joined(seperator : ",")
so in separator you can modify the string.
Output-> ("one,two,three")
The Swift equivalent to what you're describing is string interpolation. If you're thinking about things like JavaScript doing "x" + array, the equivalent in Swift is "x\(array)".
As a general note, there is an important difference between string interpolation vs the Printable protocol. Only certain classes conform to Printable. Every class can be string interpolated somehow. That's helpful when writing generic functions. You don't have to limit yourself to Printable classes.
You can print any object using the print function
or use \(name) to convert any object to a string.
Example:
let array = [1,2,3,4]
print(array) // prints "[1,2,3,4]"
let string = "\(array)" // string == "[1,2,3,4]"
print(string) // prints "[1,2,3,4]"
Create extension for an Array:
extension Array {
var string: String? {
do {
let data = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
return String(data: data, encoding: .utf8)
} catch {
return nil
}
}
}
if you have string array list , then convert to Int
let arrayList = list.map { Int($0)!}
arrayList.description
it will give you string value
for any Element type
extension Array {
func joined(glue:()->Element)->[Element]{
var result:[Element] = [];
result.reserveCapacity(count * 2);
let last = count - 1;
for (ix,item) in enumerated() {
result.append(item);
guard ix < last else{ continue }
result.append(glue());
}
return result;
}
}
Try This:
let categories = dictData?.value(forKeyPath: "listing_subcategories_id") as! NSMutableArray
let tempArray = NSMutableArray()
for dc in categories
{
let dictD = dc as? NSMutableDictionary
tempArray.add(dictD?.object(forKey: "subcategories_name") as! String)
}
let joinedString = tempArray.componentsJoined(by: ",")
use this when you want to convert list of struct type into string
struct MyStruct {
var name : String
var content : String
}
let myStructList = [MyStruct(name: "name1" , content: "content1") , MyStruct(name: "name2" , content: "content2")]
and covert your array like this way
let myString = myStructList.map({$0.name}).joined(separator: ",")
will produce ===> "name1,name2"
FOR SWIFT 3:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if textField == phoneField
{
let newString = NSString(string: textField.text!).replacingCharacters(in: range, with: string)
let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)
let decimalString = NSString(string: components.joined(separator: ""))
let length = decimalString.length
let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)
if length == 0 || (length > 10 && !hasLeadingOne) || length > 11
{
let newLength = NSString(string: textField.text!).length + (string as NSString).length - range.length as Int
return (newLength > 10) ? false : true
}
var index = 0 as Int
let formattedString = NSMutableString()
if hasLeadingOne
{
formattedString.append("1 ")
index += 1
}
if (length - index) > 3
{
let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("(%#)", areaCode)
index += 3
}
if length - index > 3
{
let prefix = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("%#-", prefix)
index += 3
}
let remainder = decimalString.substring(from: index)
formattedString.append(remainder)
textField.text = formattedString as String
return false
}
else
{
return true
}
}
If you question is something like this:
tobeFormattedString = ["a", "b", "c"]
Output = "abc"
String(tobeFormattedString)
Related
I know how to programmatically do it, but I'm sure there's a built-in way...
Every language I've used has some sort of default textual representation for a collection of objects that it will spit out when you try to concatenate the Array with a string, or pass it to a print() function, etc. Does Apple's Swift language have a built-in way of easily turning an Array into a String, or do we always have to be explicit when stringifying an array?
If the array contains strings, you can use the String's join method:
var array = ["1", "2", "3"]
let stringRepresentation = "-".join(array) // "1-2-3"
In Swift 2:
var array = ["1", "2", "3"]
let stringRepresentation = array.joinWithSeparator("-") // "1-2-3"
This can be useful if you want to use a specific separator (hypen, blank, comma, etc).
Otherwise you can simply use the description property, which returns a string representation of the array:
let stringRepresentation = [1, 2, 3].description // "[1, 2, 3]"
Hint: any object implementing the Printable protocol has a description property. If you adopt that protocol in your own classes/structs, you make them print friendly as well
In Swift 3
join becomes joined, example [nil, "1", "2"].flatMap({$0}).joined()
joinWithSeparator becomes joined(separator:) (only available to Array of Strings)
In Swift 4
var array = ["1", "2", "3"]
array.joined(separator:"-")
With Swift 5, according to your needs, you may choose one of the following Playground sample codes in order to solve your problem.
Turning an array of Characters into a String with no separator:
let characterArray: [Character] = ["J", "o", "h", "n"]
let string = String(characterArray)
print(string)
// prints "John"
Turning an array of Strings into a String with no separator:
let stringArray = ["Bob", "Dan", "Bryan"]
let string = stringArray.joined(separator: "")
print(string) // prints: "BobDanBryan"
Turning an array of Strings into a String with a separator between words:
let stringArray = ["Bob", "Dan", "Bryan"]
let string = stringArray.joined(separator: " ")
print(string) // prints: "Bob Dan Bryan"
Turning an array of Strings into a String with a separator between characters:
let stringArray = ["car", "bike", "boat"]
let characterArray = stringArray.flatMap { $0 }
let stringArray2 = characterArray.map { String($0) }
let string = stringArray2.joined(separator: ", ")
print(string) // prints: "c, a, r, b, i, k, e, b, o, a, t"
Turning an array of Floats into a String with a separator between numbers:
let floatArray = [12, 14.6, 35]
let stringArray = floatArray.map { String($0) }
let string = stringArray.joined(separator: "-")
print(string)
// prints "12.0-14.6-35.0"
Swift 2.0 Xcode 7.0 beta 6 onwards uses joinWithSeparator() instead of join():
var array = ["1", "2", "3"]
let stringRepresentation = array.joinWithSeparator("-") // "1-2-3"
joinWithSeparator is defined as an extension on SequenceType
extension SequenceType where Generator.Element == String {
/// Interpose the `separator` between elements of `self`, then concatenate
/// the result. For example:
///
/// ["foo", "bar", "baz"].joinWithSeparator("-|-") // "foo-|-bar-|-baz"
#warn_unused_result
public func joinWithSeparator(separator: String) -> String
}
Swift 3
["I Love","Swift"].joined(separator:" ") // previously joinWithSeparator(" ")
Since no one has mentioned reduce, here it is:
[0, 1, 1, 0].map {"\($0)"}.reduce("") { $0 + $1 } // "0110"
In the spirit of functional programming ๐ค
In Swift 4
let array:[String] = ["Apple", "Pear ","Orange"]
array.joined(separator: " ")
To change an array of Optional/Non-Optional Strings
//Array of optional Strings
let array : [String?] = ["1",nil,"2","3","4"]
//Separator String
let separator = ","
//flatMap skips the nil values and then joined combines the non nil elements with the separator
let joinedString = array.flatMap{ $0 }.joined(separator: separator)
//Use Compact map in case of **Swift 4**
let joinedString = array.compactMap{ $0 }.joined(separator: separator
print(joinedString)
Here flatMap, compactMap skips the nil values in the array and appends the other values to give a joined string.
Nowadays, in iOS 13+ and macOS 10.15+, we might use ListFormatter:
let formatter = ListFormatter()
let names = ["Moe", "Larry", "Curly"]
if let string = formatter.string(from: names) {
print(string)
}
That will produce a nice, natural language string representation of the list. A US user will see:
Moe, Larry, and Curly
It will support any languages for which (a) your app has been localized; and (b) the userโs device is configured. For example, a German user with an app supporting German localization, would see:
Moe, Larry und Curly
Mine works on NSMutableArray with componentsJoinedByString
var array = ["1", "2", "3"]
let stringRepresentation = array.componentsJoinedByString("-") // "1-2-3"
In Swift 2.2 you may have to cast your array to NSArray to use componentsJoinedByString(",")
let stringWithCommas = (yourArray as NSArray).componentsJoinedByString(",")
let arrayTemp :[String] = ["Mani","Singh","iOS Developer"]
let stringAfterCombining = arrayTemp.componentsJoinedByString(" ")
print("Result will be >>> \(stringAfterCombining)")
Result will be >>> Mani Singh iOS Developer
If you want to ditch empty strings in the array.
["Jet", "Fire"].filter { !$0.isEmpty }.joined(separator: "-")
If you want to filter nil values as well:
["Jet", nil, "", "Fire"].flatMap { $0 }.filter { !$0.isEmpty }.joined(separator: "-")
you can use joined() to get a single String when you have array of struct also.
struct Person{
let name:String
let contact:String
}
You can easily produce string using map() & joined()
PersonList.map({"\($0.name) - \($0.contact)"}).joined(separator: " | ")
output:
Jhon - 123 | Mark - 456 | Ben - 789
if you want convert custom object array to string or comma separated string (csv) you can use
var stringIds = (self.mylist.map{$0.id ?? 0}).map{String($0)}.joined(separator: ",")
credit to : urvish modi
post: Convert an array of Ints to a comma separated string
A separator can be a bad idea for some languages like Hebrew or Japanese.
Try this:
// Array of Strings
let array: [String] = ["red", "green", "blue"]
let arrayAsString: String = array.description
let stringAsData = arrayAsString.data(using: String.Encoding.utf16)
let arrayBack: [String] = try! JSONDecoder().decode([String].self, from: stringAsData!)
For other data types respectively:
// Set of Doubles
let set: Set<Double> = [1, 2.0, 3]
let setAsString: String = set.description
let setStringAsData = setAsString.data(using: String.Encoding.utf16)
let setBack: Set<Double> = try! JSONDecoder().decode(Set<Double>.self, from: setStringAsData!)
You can either use loops for getting this done. Or by using map.
By mapping:
let array = ["one" , "two" , "three"]
array.map({$0}).joined(seperator : ",")
so in separator you can modify the string.
Output-> ("one,two,three")
The Swift equivalent to what you're describing is string interpolation. If you're thinking about things like JavaScript doing "x" + array, the equivalent in Swift is "x\(array)".
As a general note, there is an important difference between string interpolation vs the Printable protocol. Only certain classes conform to Printable. Every class can be string interpolated somehow. That's helpful when writing generic functions. You don't have to limit yourself to Printable classes.
You can print any object using the print function
or use \(name) to convert any object to a string.
Example:
let array = [1,2,3,4]
print(array) // prints "[1,2,3,4]"
let string = "\(array)" // string == "[1,2,3,4]"
print(string) // prints "[1,2,3,4]"
Create extension for an Array:
extension Array {
var string: String? {
do {
let data = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
return String(data: data, encoding: .utf8)
} catch {
return nil
}
}
}
if you have string array list , then convert to Int
let arrayList = list.map { Int($0)!}
arrayList.description
it will give you string value
for any Element type
extension Array {
func joined(glue:()->Element)->[Element]{
var result:[Element] = [];
result.reserveCapacity(count * 2);
let last = count - 1;
for (ix,item) in enumerated() {
result.append(item);
guard ix < last else{ continue }
result.append(glue());
}
return result;
}
}
Try This:
let categories = dictData?.value(forKeyPath: "listing_subcategories_id") as! NSMutableArray
let tempArray = NSMutableArray()
for dc in categories
{
let dictD = dc as? NSMutableDictionary
tempArray.add(dictD?.object(forKey: "subcategories_name") as! String)
}
let joinedString = tempArray.componentsJoined(by: ",")
use this when you want to convert list of struct type into string
struct MyStruct {
var name : String
var content : String
}
let myStructList = [MyStruct(name: "name1" , content: "content1") , MyStruct(name: "name2" , content: "content2")]
and covert your array like this way
let myString = myStructList.map({$0.name}).joined(separator: ",")
will produce ===> "name1,name2"
FOR SWIFT 3:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if textField == phoneField
{
let newString = NSString(string: textField.text!).replacingCharacters(in: range, with: string)
let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)
let decimalString = NSString(string: components.joined(separator: ""))
let length = decimalString.length
let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)
if length == 0 || (length > 10 && !hasLeadingOne) || length > 11
{
let newLength = NSString(string: textField.text!).length + (string as NSString).length - range.length as Int
return (newLength > 10) ? false : true
}
var index = 0 as Int
let formattedString = NSMutableString()
if hasLeadingOne
{
formattedString.append("1 ")
index += 1
}
if (length - index) > 3
{
let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("(%#)", areaCode)
index += 3
}
if length - index > 3
{
let prefix = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("%#-", prefix)
index += 3
}
let remainder = decimalString.substring(from: index)
formattedString.append(remainder)
textField.text = formattedString as String
return false
}
else
{
return true
}
}
If you question is something like this:
tobeFormattedString = ["a", "b", "c"]
Output = "abc"
String(tobeFormattedString)
So i've taken my bundle version and save it in an array but it s of type String. I ve tried and .map it to be Int but i receive Cannot invoke initializer for type 'Int' with an argument list of type''((String.Element))
let versionName = String(describing: Bundle.main.infoDictionary!["CFBundleShortVersionString"]!) // 1.9.1
let versionNumeral = Array(versionName.westernArabicNumeralsOnly) // ["1","9","1"]
let convertedToInt = versionNumeral.map {Int($0)} // so i want it here to be [1, 9, 1] so I can add them between them.
for element in convertedToInt {
total += element
}
.westernArabicNumeralsOnly is a string extension that removes my dots from version and only let the numbers
extension String {
var westernArabicNumeralsOnly: String {
let pattern = UnicodeScalar("0")..."9"
return String(unicodeScalars
.flatMap { pattern ~= $0 ? Character($0) : nil })
}
}
There is no direct conversion between Characters and Ints. If you are wanting to extract the version numbers from the string the following might be a better way to do it. It would also allow for version numbers greater than 9
let versionName = String(describing: Bundle.main.infoDictionary!["CFBundleShortVersionString"]!) // 1.9.1
let versionComponents = versionName.components(separatedBy: ".")
let convertedToInt = versionComponents.map {Int($0)}
This version would output an array of Int?. If you want an array of Int then you could use
let convertedToInt = versionComponents.map {Int($0)!}
but you'd have to be sure you aren't sent a string with non-numerical characters in it.
I'd use this:
let versionString = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? ""
let versionInts = versionString.components(separatedBy: ".").map { Int($0) ?? 0 }
Fetch number easily without westernArabicNumeralsOnly function
let versionName = String(describing: Bundle.main.infoDictionary!["CFBundleShortVersionString"]!) // 1.9.1
let versionNumeral = Array(versionName.components(separatedBy: ".")) // ["1","9","1"]
let convertedToInt = versionNumeral.map{Int($0)} // [1,9,1]
var total = 0
for element in convertedToInt {
total = total + element!
}
print(total) // 11
How could we convert anyobject to string in swift 3, it's very easy in the older version by using.
var str = toString(AnyObject)
I tried String(AnyObject) but the output is always optional, even when i'm sure that AnyObject is not a optional value.
The compiler suggests that you replace your code with:
let s = String(describing: str)
One other option is available if you have a situation where you want to silently fail with an empty string rather than store something that might not originally be a string as a string.
let s = str as? String ?? ""
else you have the ways of identifying and throwing an error in the answers above/below.
Here's three options for you:
Option 1 - if let
if let b = a as? String {
print(b) // Was a string
} else {
print("Error") // Was not a string
}
Option 2 - guard let
guard let b = a as? String
else {
print("Error") // Was not a string
return // needs a return or break here
}
print(b) // Was a string
Option 3 - let with ?? (null coalescing operator)
let b = a as? String ?? ""
print(b) // Print a blank string if a was not a string
Here's a simple function (repl.it) that will mash any value into a string, with nil becoming an empty string. I found it useful for dealing with JSON that inconsistently uses null, blank, numbers, and numeric strings for IDs.
import Foundation
func toString(_ value: Any?) -> String {
return String(describing: value ?? "")
}
let d: NSDictionary = [
"i" : 42,
"s" : "Hello, World!"
]
dump(toString(d["i"]))
dump(toString(d["s"]))
dump(toString(d["x"]))
Prints:
- "42"
- "Hello, World!"
- ""
Try
let a = "Test" as AnyObject
guard let b = a as? String else { // Something went wrong handle it here }
print(b) // Test
try this -
var str:AnyObject?
str = "Hello, playground" as AnyObject?
if let value = str
{
var a = value as! String
}
OR
var a = str as? String
I have a string composed of words, some of which contain punctuation, which I would like to remove, but I have been unable to figure out how to do this.
For example if I have something like
var words = "Hello, this : is .. a string?"
I would like to be able to create an array with
"[Hello, this, is, a, string]"
My original thought was to use something like words.stringByTrimmingCharactersInSet() to remove any characters I didn't want but that would only take characters off the ends.
I thought maybe I could iterate through the string with something in the vein of
for letter in words {
if NSCharacterSet.punctuationCharacterSet.characterIsMember(letter){
//remove that character from the string
}
}
but I'm unsure how to remove the character from the string. I'm sure there are some problems with the way that if statement is set up, as well, but it shows my thought process.
Xcode 11.4 โข Swift 5.2 or later
extension StringProtocol {
var words: [SubSequence] {
split(whereSeparator: \.isLetter.negation)
}
}
extension Bool {
var negation: Bool { !self }
}
let sentence = "Hello, this : is .. a string?"
let words = sentence.words // ["Hello", "this", "is", "a", "string"]
String has a enumerateSubstringsInRange() method.
With the .ByWords option, it detects word boundaries and
punctuation automatically:
Swift 3/4:
let string = "Hello, this : is .. a \"string\"!"
var words : [String] = []
string.enumerateSubstrings(in: string.startIndex..<string.endIndex,
options: .byWords) {
(substring, _, _, _) -> () in
words.append(substring!)
}
print(words) // [Hello, this, is, a, string]
Swift 2:
let string = "Hello, this : is .. a \"string\"!"
var words : [String] = []
string.enumerateSubstringsInRange(string.characters.indices,
options: .ByWords) {
(substring, _, _, _) -> () in
words.append(substring!)
}
print(words) // [Hello, this, is, a, string]
This works with Xcode 8.1, Swift 3:
First define general-purpose extension for filtering by CharacterSet:
extension String {
func removingCharacters(inCharacterSet forbiddenCharacters:CharacterSet) -> String
{
var filteredString = self
while true {
if let forbiddenCharRange = filteredString.rangeOfCharacter(from: forbiddenCharacters) {
filteredString.removeSubrange(forbiddenCharRange)
}
else {
break
}
}
return filteredString
}
}
Then filter using punctuation:
let s:String = "Hello, world!"
s.removingCharacters(inCharacterSet: CharacterSet.punctuationCharacters) // => "Hello world"
let charactersToRemove = NSCharacterSet.punctuationCharacterSet().invertedSet
let aWord = "".join(words.componentsSeparatedByCharactersInSet(charactersToRemove))
An alternate way to filter characters from a set and obtain an array of words is by using the array's filter and reduce methods. It's not as compact as other answers, but it shows how the same result can be obtained in a different way.
First define an array of the characters to remove:
let charactersToRemove = Set(Array(".:?,"))
next convert the input string into an array of characters:
let arrayOfChars = Array(words)
Now we can use reduce to build a string, obtained by appending the elements from arrayOfChars, but skipping all the ones included in charactersToRemove:
let filteredString = arrayOfChars.reduce("") {
let str = String($1)
return $0 + (charactersToRemove.contains($1) ? "" : str)
}
This produces a string without the punctuation characters (as defined in charactersToRemove).
The last 2 steps:
split the string into an array of words, using the blank character as separator:
let arrayOfWords = filteredString.componentsSeparatedByString(" ")
last, remove all empty elements:
let finalArrayOfWords = arrayOfWords.filter { $0.isEmpty == false }
NSScaner way:
let words = "Hello, this : is .. a string?"
//
let scanner = NSScanner(string: words)
var wordArray:[String] = []
var word:NSString? = ""
while(!scanner.atEnd) {
var sr = scanner.scanCharactersFromSet(NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKMNOPQRSTUVWXYZ"), intoString: &word)
if !sr {
scanner.scanLocation++
continue
}
wordArray.append(String(word!))
}
println(wordArray)
How can I convert a String "Hello" to an Array ["H","e","l","l","o"] in Swift?
In Objective-C I have used this:
NSMutableArray *characters = [[NSMutableArray alloc] initWithCapacity:[myString length]];
for (int i=0; i < [myString length]; i++) {
NSString *ichar = [NSString stringWithFormat:#"%c", [myString characterAtIndex:i]];
[characters addObject:ichar];
}
It is even easier in Swift:
let string : String = "Hello ๐ถ๐ฎ ๐ฉ๐ช"
let characters = Array(string)
println(characters)
// [H, e, l, l, o, , ๐ถ, ๐ฎ, , ๐ฉ๐ช]
This uses the facts that
an Array can be created from a SequenceType, and
String conforms to the SequenceType protocol, and its sequence generator
enumerates the characters.
And since Swift strings have full support for Unicode, this works even with characters
outside of the "Basic Multilingual Plane" (such as ๐ถ) and with extended grapheme
clusters (such as ๐ฉ๐ช, which is actually composed of two Unicode scalars).
Update: As of Swift 2, String does no longer conform to
SequenceType, but the characters property provides a sequence of the
Unicode characters:
let string = "Hello ๐ถ๐ฎ ๐ฉ๐ช"
let characters = Array(string.characters)
print(characters)
This works in Swift 3 as well.
Update: As of Swift 4, String is (again) a collection of its
Characters:
let string = "Hello ๐ถ๐ฎ ๐ฉ๐ช"
let characters = Array(string)
print(characters)
// ["H", "e", "l", "l", "o", " ", "๐ถ", "๐ฎ", " ", "๐ฉ๐ช"]
Edit (Swift 4)
In Swift 4, you don't have to use characters to use map(). Just do map() on String.
let letters = "ABC".map { String($0) }
print(letters) // ["A", "B", "C"]
print(type(of: letters)) // Array<String>
Or if you'd prefer shorter: "ABC".map(String.init) (2-bytes ๐)
Edit (Swift 2 & Swift 3)
In Swift 2 and Swift 3, You can use map() function to characters property.
let letters = "ABC".characters.map { String($0) }
print(letters) // ["A", "B", "C"]
Original (Swift 1.x)
Accepted answer doesn't seem to be the best, because sequence-converted String is not a String sequence, but Character:
$ swift
Welcome to Swift! Type :help for assistance.
1> Array("ABC")
$R0: [Character] = 3 values {
[0] = "A"
[1] = "B"
[2] = "C"
}
This below works for me:
let str = "ABC"
let arr = map(str) { s -> String in String(s) }
Reference for a global function map() is here: http://swifter.natecook.com/func/map/
There is also this useful function on String: components(separatedBy: String)
let string = "1;2;3"
let array = string.components(separatedBy: ";")
print(array) // returns ["1", "2", "3"]
Works well to deal with strings separated by a character like ";" or even "\n"
For Swift version 5.3 its easy as:
let string = "Hello world"
let characters = Array(string)
print(characters)
// ["H", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
Updated for Swift 4
Here are 3 ways.
//array of Characters
let charArr1 = [Character](myString)
//array of String.element
let charArr2 = Array(myString)
for char in myString {
//char is of type Character
}
In some cases, what people really want is a way to convert a string into an array of little strings with 1 character length each. Here is a super efficient way to do that:
//array of String
var strArr = myString.map { String($0)}
Swift 3
Here are 3 ways.
let charArr1 = [Character](myString.characters)
let charArr2 = Array(myString.characters)
for char in myString.characters {
//char is of type Character
}
In some cases, what people really want is a way to convert a string into an array of little strings with 1 character length each. Here is a super efficient way to do that:
var strArr = myString.characters.map { String($0)}
Or you can add an extension to String.
extension String {
func letterize() -> [Character] {
return Array(self.characters)
}
}
Then you can call it like this:
let charArr = "Cat".letterize()
An easy way to do this is to map the variable and return each Character as a String:
let someText = "hello"
let array = someText.map({ String($0) }) // [String]
The output should be ["h", "e", "l", "l", "o"].
for the function on String: components(separatedBy: String)
in Swift 5.1
have change to:
string.split(separator: "/")
Martin R answer is the best approach, and as he said, because String conforms the SquenceType protocol, you can also enumerate a string, getting each character on each iteration.
let characters = "Hello"
var charactersArray: [Character] = []
for (index, character) in enumerate(characters) {
//do something with the character at index
charactersArray.append(character)
}
println(charactersArray)
let string = "hell0"
let ar = Array(string.characters)
print(ar)
In Swift 4, as String is a collection of Character, you need to use map
let array1 = Array("hello") // Array<Character>
let array2 = Array("hello").map({ "\($0)" }) // Array<String>
let array3 = "hello".map(String.init) // Array<String>
You can also create an extension:
var strArray = "Hello, playground".Letterize()
extension String {
func Letterize() -> [String] {
return map(self) { String($0) }
}
}
func letterize() -> [Character] {
return Array(self.characters)
}
Suppose you have four text fields otpOneTxt, otpTwoTxt, otpThreeTxt, otpFourTxt and a string getOtp.
let getup = "5642"
let array = self.getOtp.map({ String($0) })
otpOneTxt.text = array[0] //5
otpTwoTxt.text = array[1] //6
otpThreeTxt.text = array[2] //4
otpFourTxt.text = array[3] //2
let str = "cdcd"
let characterArr = str.reduce(into: [Character]()) { result, letter in
result.append(letter)
}
print(characterArr)
//["c", "d", "c", "d"]