for example:
var a = [1, 2, 3] // Ints
var s = \",\".join(a) // EXC_BAD_ACCESS
Is it possible to make the join function return \"1,2,3\
Even if you can't make join work for custom types, there's an easy workaround. All you have to do is define a method on your class (or extend a built-in class) to return a string, and then map that into the join.
So, for example, we could have:
extension Int {
func toString() -> String {
return "\(self)" // trivial example here, but yours could be more complex
}
Then you can do:
let xs = [1, 2, 3]
let s = join(xs.map { $0.toString() })
I wouldn't recommend using .description
for this purpose, as by default it will call .debugDescription
, which is not particularly useful in production code.
In any case, it would be better to provide an explicit method for transforming into a string suitable for joining, rather than relying on a generic 'description' method which you may change at a later date.
A Swift 3 solution
public extension Sequence where Iterator.Element: CustomStringConvertible {
func joined(seperator: String) -> String {
return self.map({ (val) -> String in
"\(val)"
}).joined(separator: seperator)
}
}
And just to make your life more complete, starting from Xcode 8.0 beta 1 in Swift 3 you should NOW use [String].joined(separator: ",")
.
This is the new "ed/ing" naming rule for Swift APIs:
Name functions and methods according to their side-effects
- Those without side-effects should read as noun phrases, e.g. x.distance(to: y), i.successor().
- Those with side-effects should read as imperative verb phrases, e.g., print(x), x.sort(), x.append(y).
- Name Mutating/nonmutating method pairs consistently. A mutating method will often have a nonmutating variant with similar semantics, but that returns a new value rather than updating an instance in-place. Swift: API Design Guidelines
From Xcode 7.0 beta 6 in Swift 2 now you should use [String].joinWithSeparator(",")
.
In your case you still need to change Int to String type, therefore I added map()
.
var a = [1, 2, 3] // [1, 2, 3]
var s2 = a.map { String($0) }.joinWithSeparator(",") // "1,2,3"
From Xcode 8.0 beta 1 in Swift 3 code slightly changes to
[String].joined(separator: ",")
.
var s3 = a.map { String($0) }.joined(separator: ",") // "1,2,3"
try this
var a = [1, 2, 3] // Ints
var s = ",".join(a.map { $0.description })
or add this extension
extension String {
func join<S : SequenceType where S.Generator.Element : Printable>(elements: S) -> String {
return self.join(map(elements){ $0.description })
}
// use this if you don't want it constrain to Printable
//func join<S : SequenceType>(elements: S) -> String {
// return self.join(map(elements){ "\($0)" })
//}
}
var a = [1, 2, 3] // Ints
var s = ",".join(a) // works with new overload of join
join is defined as
extension String {
func join<S : SequenceType where String == String>(elements: S) -> String
}
which means it takes a sequence of string, you can't pass a sequence of int to it.
The simplest way is a variation of @BryanChen's answer:
",".join(a.map { String($0) } )