62 lines
1.8 KiB
Swift
62 lines
1.8 KiB
Swift
//
|
|
// ArticleSorter.swift
|
|
// NetNewsWire
|
|
//
|
|
// Created by Phil Viso on 9/8/19.
|
|
// Copyright © 2019 Ranchero Software. All rights reserved.
|
|
//
|
|
|
|
import Articles
|
|
import Foundation
|
|
|
|
protocol SortableArticle {
|
|
var sortableName: String { get }
|
|
var sortableDate: Date { get }
|
|
var sortableArticleID: String { get }
|
|
var sortableFeedID: String { get }
|
|
}
|
|
|
|
struct ArticleSorter {
|
|
|
|
static func sortedByDate<T: SortableArticle>(articles: [T],
|
|
sortDirection: ComparisonResult,
|
|
groupByFeed: Bool) -> [T] {
|
|
if groupByFeed {
|
|
return sortedByFeedName(articles: articles, sortByDateDirection: sortDirection)
|
|
} else {
|
|
return sortedByDate(articles: articles, sortDirection: sortDirection)
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
private static func sortedByFeedName<T: SortableArticle>(articles: [T],
|
|
sortByDateDirection: ComparisonResult) -> [T] {
|
|
// Group articles by "feed-feedID" - feed ID is used to differentiate between
|
|
// two feeds that have the same name
|
|
let groupedArticles = Dictionary(grouping: articles) { "\($0.sortableName.lowercased())-\($0.sortableFeedID)" }
|
|
return groupedArticles
|
|
.sorted { $0.key < $1.key }
|
|
.flatMap { (tuple) -> [T] in
|
|
let (_, articles) = tuple
|
|
|
|
return sortedByDate(articles: articles, sortDirection: sortByDateDirection)
|
|
}
|
|
}
|
|
|
|
private static func sortedByDate<T: SortableArticle>(articles: [T],
|
|
sortDirection: ComparisonResult) -> [T] {
|
|
return articles.sorted { (article1, article2) -> Bool in
|
|
if article1.sortableDate == article2.sortableDate {
|
|
return article1.sortableArticleID < article2.sortableArticleID
|
|
}
|
|
if sortDirection == .orderedDescending {
|
|
return article1.sortableDate > article2.sortableDate
|
|
}
|
|
|
|
return article1.sortableDate < article2.sortableDate
|
|
}
|
|
}
|
|
|
|
}
|