Skip to content

Instantly share code, notes, and snippets.

@ZevEisenberg
Created December 19, 2017 01:09
Show Gist options
  • Save ZevEisenberg/5c2edd906022be4a7e193c216e45e20e to your computer and use it in GitHub Desktop.
Save ZevEisenberg/5c2edd906022be4a7e193c216e45e20e to your computer and use it in GitHub Desktop.
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