Last active
March 12, 2018 08:46
-
-
Save tutumagi/370ab8da664d839dea7334d52561cabb to your computer and use it in GitHub Desktop.
[ArraySection] Split Array Section by Year/Month/Day
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
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