Concatenating an array of optional NSAttributedStrings
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) -&gt; 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) -&gt; NSAttributedString {
        let finalString = NSMutableAttributedString()
        for (index, string) in enumerate() {
            if index &gt; 0 {
                finalString.appendAttributedString(separator)
            }
            finalString.appendAttributedString(string)
        }
        return finalString
    }
}




Update: The Swift language changes constantly. For the convenience
of future readers, here is an update to Swift 4 of the above code:

extension Sequence where Element: NSAttributedString {

    func join(withSeparator separator: NSAttributedString) -&gt; NSAttributedString {
        let finalString = NSMutableAttributedString()
        for (index, string) in enumerated() {
            if index &gt; 0 {
                finalString.append(separator)
            }
            finalString.append(string)
        }
        return finalString
    }
}


Also flatMap has been renamed to compactMap:

let attributedStrings = optionalAttributedStrings.compactMap { $0 }