Skip to content

Instantly share code, notes, and snippets.

@tutumagi
Last active March 12, 2018 08:46
Show Gist options
  • Save tutumagi/370ab8da664d839dea7334d52561cabb to your computer and use it in GitHub Desktop.
Save tutumagi/370ab8da664d839dea7334d52561cabb to your computer and use it in GitHub Desktop.
[ArraySection] Split Array Section by Year/Month/Day
import Foundation
protocol DateElement {
var dateKey: Date {get set}
}
protocol DateSection : DateElement {
associatedtype Element: DateElement, Equatable
var elements: [Element] {get set}
}
// 分区类型
public enum SplitType : Int {
case none // 不分区
case day // 按天分区
case month // 按月分区
case year // 按年分区
func formatterStr() -> String {
switch self {
case .day:
return "yyyyMMdd"
case .month:
return "yyyyMM"
case .year:
return "yyyy"
case .none:
return "yyyyMMddHHmmss"
}
}
func name(_ date: Date) -> String {
return (date as NSDate).str(withFormatterStr: formatterStr())
}
func date(_ name: String) -> Date {
return NSDate.init(fromStr: name, formatterStr: formatterStr())! as Date
}
}
extension Array where Element: DateSection {
/// 添加新的元素数组,进行分区。增量操作
///
/// - Parameters:
/// - list: 新的元素数组
/// - createSection: 分区的Section的构造方法 (PS:就是创建一个新的DateSection的方法,如果有更好的直接通过DateSection 协议实现,希望可以comment)
/// - type: 分区类型
mutating func add(newList list:[Element.Element], createSection: ()->Element, splitType type: SplitType = .none) {
// 是否需要分区
let shouldSplit = (type != .none)
self = list.reduce(into: self) { (result, item) in
let itemDateName = type.name(item.dateKey)
var filter = result
if shouldSplit {
// 这里filter出来的数据不是拷贝,可以直接修改原数据,good
filter = result.filter({ (section) -> Bool in
type.name(section.dateKey) == itemDateName
})
}
var existSection = filter.first
if existSection == nil {
// 这里需要创建一个 Element类型的实例
existSection = createSection()
result.append(existSection!)
if shouldSplit {
existSection?.dateKey = item.dateKey
result.sortByDate()
}
}
if !existSection!.elements.contains{ $0 == item} {
existSection!.elements.append(item)
existSection!.elements.sortByDate()
}
}
}
}
extension Array where Element: DateElement {
mutating func sortByDate() {
self.sort(by: { (left, right) -> Bool in
let ret = left.dateKey.compare(right.dateKey)
return (ret == ComparisonResult.orderedAscending ? false : true)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment