например:
var a = [1, 2, 3] // Ints
var s = ",".join(a) // EXC_BAD_ACCESS
Можно ли вернуть функцию соединения "1,2,3"?
Расширить Int (или другие настраиваемые типы), чтобы соответствовать некоторым протоколам?
например:
var a = [1, 2, 3] // Ints
var s = ",".join(a) // EXC_BAD_ACCESS
Можно ли вернуть функцию соединения "1,2,3"?
Расширить Int (или другие настраиваемые типы), чтобы соответствовать некоторым протоколам?
попробуйте это
var a = [1, 2, 3] // Ints
var s = ",".join(a.map { $0.description })
или добавьте это расширение
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 определяется как
extension String {
func join<S : SequenceType where String == String>(elements: S) -> String
}
что означает, что он принимает последовательность строк, вы не можете передать ему последовательность int.
От Xcode 7.0 beta 6 в Swift 2 теперь вы должны использовать [String].joinWithSeparator(",")
.
В вашем случае вам все равно нужно изменить Int на тип String, поэтому я добавил map()
.
var a = [1, 2, 3] // [1, 2, 3]
var s2 = a.map { String($0) }.joinWithSeparator(",") // "1,2,3"
От Xcode 8.0 beta 1 в Swift 3 код слегка меняется на
[String].joined(separator: ",")
.
var s3 = a.map { String($0) }.joined(separator: ",") // "1,2,3"
И чтобы сделать вашу жизнь более полной, начиная с Xcode 8.0 beta 1 в Swift 3, вы должны использовать NOW [String].joined(separator: ",")
.
Это новое правило "ed/ing" для API Swift:
Функции и методы имени в соответствии с их побочными эффектами
- Те, у кого нет побочных эффектов, следует читать как существительные, например. x.distance(to: y), i.successor().
- Те, у кого есть побочные эффекты, должны читать как императивные фразы глагола, например print (x), x.sort(), x.append(y).
- Имя Параметр Mutating/nonmutating последовательно. У мутирующего метода часто будет вариант без мутаций с аналогичной семантикой, но он возвращает новое значение, а не обновляет экземпляр на месте. Swift: Руководство по разработке API
Самый простой способ - это вариант ответа @BryanChen:
",".join(a.map { String($0) } )
Даже если вы не можете выполнить совместную работу для пользовательских типов, это простое решение. Все, что вам нужно сделать, это определить метод на вашем классе (или расширить встроенный класс), чтобы вернуть строку, а затем сопоставить ее с объединением.
Так, например, мы могли бы:
extension Int {
func toString() -> String {
return "\(self)" // trivial example here, but yours could be more complex
}
Затем вы можете сделать:
let xs = [1, 2, 3]
let s = join(xs.map { $0.toString() })
Я бы не рекомендовал использовать .description
для этой цели, так как по умолчанию он вызывается .debugDescription
, что не особенно полезно в производственном коде.
В любом случае было бы лучше указать явный метод преобразования в строку, подходящую для соединения, вместо того чтобы полагаться на общий метод описания, который вы можете изменить позже.
Решение Swift 3
public extension Sequence where Iterator.Element: CustomStringConvertible {
func joined(seperator: String) -> String {
return self.map({ (val) -> String in
"\(val)"
}).joined(separator: seperator)
}
}