The second and third approach combine two tasks into one:
- Extract the non-nil elements from the given array of optional
attributed strings, and
- concatenate these with a given separator.
My suggestion is to separate these concerns. This rules out #2 and #3
and leaves us with your #1 approach, the extension method on SequenceType.
Another disadvantage of the extension _ArrayType is that it uses an internal type,
so that might break in a future version of Swift.
The flatMap() method from the Swift standard library already provides a method for the first task:
let attributedStrings = optionalAttributedStrings.flatMap { $0 }
and this can be combined with your extension method by the caller:
let joined = optionalAttributedStrings.flatMap { $0 }.join(withSeparator: separator)
A user might also want to concatenate non-optional strings, which
works with the extension method:
let joined = attributedStrings.join(withSeparator: separator)
but not with the other two approaches.
Another argument for approach #1 is that it resembles
the existing method to join strings:
extension SequenceType where Generator.Element == String {
public func joinWithSeparator(separator: String) -> String
}
The method itself can be improved. The reduce() method creates a new
NSMutableAttributedString in each iteration. Better create only one
and append all elements (similar as on your join() function):
extension SequenceType where Generator.Element: NSAttributedString {
func join(withSeparator separator: NSAttributedString) -> NSAttributedString {
let finalString = NSMutableAttributedString()
for (index, string) in enumerate() {
if index > 0 {
finalString.appendAttributedString(separator)
}
finalString.appendAttributedString(string)
}
return finalString
}
}