Created
December 19, 2017 01:09
-
-
Save ZevEisenberg/5c2edd906022be4a7e193c216e45e20e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct SectionedArray<GroupKey, Item> where GroupKey: Comparable & Hashable { | |
struct Section { | |
let key: GroupKey | |
var items: [Item] | |
} | |
var sections: [Section] | |
var count: Int { | |
return sections.count | |
} | |
var first: Section? { | |
return sections.first | |
} | |
var last: Section? { | |
return sections.last | |
} | |
public var isEmpty: Bool { | |
return sections.isEmpty | |
} | |
init<S: Sequence>(_ sequence: S, sortingBy isOrderedBefore: (Item, Item) throws -> Bool, groupingBy groupFunction: (Item) throws -> GroupKey) rethrows where S.Element == Item { | |
let sortedItems = try sequence.sorted(by: isOrderedBefore) | |
let grouped = try Dictionary(grouping: sortedItems, by: groupFunction) | |
let sortedGroups = grouped.sorted { $0.key < $1.key } | |
sections = sortedGroups.map { Section(key: $0.key, items: $0.value) } | |
} | |
init(sections: [Section]) { | |
self.sections = sections | |
} | |
} | |
extension SectionedArray: Collection { | |
func index(after i: Int) -> Int { | |
return i + 1 | |
} | |
subscript(position: Int) -> SectionedArray<GroupKey, Item>.Section { | |
return sections[position] | |
} | |
var startIndex: Int { | |
return 0 | |
} | |
var endIndex: Int { | |
return count | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment