Hi All,

I’m coding for section like data structure. 
For example:

I have an Album struct, which has many MediaItems.
It has a sectioned property called "sectionedMediaItemInfos", which is an array 
of sections.
Each section represents for a disc, and has an "items" array contains all 
MedaItems in that disc.

The define code is like:

```Swift
public struct Album {
    public let sectionedMediaItemInfos: [Sectioned<MediaItemInfo>]?
}

public struct Sectioned<Item> : SectionProtocol {
    public let title: String?
    public let items: [Item]
    
    public init() {
        items = []
        title = nil
    }
}

public protocol SectionProtocol {
    associatedtype SectionItemType
    var items: [SectionItemType] { get }
}
```

Now I want to define some extra properties for sections array, like
"sectionMediaItemInfos"."itemsCount" that count all items in each sections.
So I can write that extension:

```Swift
public extension Array where Element : SectionProtocol {
    
    var itemsCount: Int {
        return reduce(0) { (result, section) in result + section.items.count }
    }

}
```

So I can get my itemsCount with code like:

```Swift
album.sectionedMediaItemInfos.itemsCount
```

That looks good.

Then I want to define code to return all items in this sectioned property.


```Swift
public extension Array where Element : SectionProtocol {
    var items: [SectionProtocol.SectionItemType] {
        return .flatMap { $0.items }
    }
}
```

This doesn’t work. It reported as "Cannot use associated type 'SectionItemType' 
outside of its protocol"

The only way to achieve my goals is to untyped the extended "items" property:

```Swift
public extension Array where Element : SectionProtocol {
    var items: [Any] {
        return self.flatMap { $0.items }
    }
}
```

Which is not perfect for this case.


So in this special case, I think allow use associated type outside of its 
protocol is necessary.

And we may allow define protocol with generic type. That would be more 
convenient.


```Swift
public struct Album {
    public let sectionedMediaItemInfos: [Sectioned<MediaItemInfo>]?
}


public struct Sectioned<Item> : SectionProtocol {
    public let title: String?
    public let items: [Item]
    
    public init() {
        items = []
        title = nil
    }
}

public protocol SectionProtocol<SectionItemType> {
    var items: [SectionItemType] { get }
}


public extension Array where Element : SectionProtocol {
    var items: [Element.SectionItemType] {
        return self.flatMap { $0.items }
    }
}

```

Thank all!

Jiannan



_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to