2019-09-08 23:48:50 +02:00
|
|
|
//
|
|
|
|
// 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 }
|
2019-09-13 14:43:28 +02:00
|
|
|
var sortableArticleID: String { get }
|
|
|
|
var sortableFeedID: String { get }
|
2019-09-08 23:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct ArticleSorter {
|
2019-09-13 14:43:28 +02:00
|
|
|
|
2019-09-08 23:48:50 +02:00
|
|
|
static func sortedByDate<T: SortableArticle>(articles: [T],
|
|
|
|
sortDirection: ComparisonResult,
|
|
|
|
groupByFeed: Bool) -> [T] {
|
2019-09-13 14:43:28 +02:00
|
|
|
if groupByFeed {
|
|
|
|
return sortedByFeedName(articles: articles, sortByDateDirection: sortDirection)
|
|
|
|
} else {
|
|
|
|
return sortedByDate(articles: articles, sortDirection: sortDirection)
|
2019-09-08 23:48:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: -
|
2019-09-13 14:43:28 +02:00
|
|
|
|
|
|
|
private static func sortedByFeedName<T: SortableArticle>(articles: [T],
|
|
|
|
sortByDateDirection: ComparisonResult) -> [T] {
|
|
|
|
// Group articles by feed - feed ID is used to differentiate between
|
|
|
|
// two feeds that have the same name
|
|
|
|
var groupedArticles = Dictionary(grouping: articles) { "\($0.sortableName.lowercased())-\($0.sortableFeedID)" }
|
|
|
|
|
|
|
|
// Sort the articles within each group
|
|
|
|
for tuple in groupedArticles {
|
|
|
|
groupedArticles[tuple.key] = sortedByDate(articles: tuple.value,
|
|
|
|
sortDirection: sortByDateDirection)
|
2019-09-08 23:48:50 +02:00
|
|
|
}
|
2019-09-13 14:43:28 +02:00
|
|
|
|
|
|
|
// Flatten the articles dictionary back into an array sorted by feed name
|
|
|
|
var sortedArticles: [T] = []
|
|
|
|
for feedName in groupedArticles.keys.sorted() {
|
|
|
|
sortedArticles.append(contentsOf: groupedArticles[feedName] ?? [])
|
2019-09-08 23:48:50 +02:00
|
|
|
}
|
2019-09-13 14:43:28 +02:00
|
|
|
|
|
|
|
return sortedArticles
|
|
|
|
}
|
|
|
|
|
|
|
|
private static func sortedByDate<T: SortableArticle>(articles: [T],
|
|
|
|
sortDirection: ComparisonResult) -> [T] {
|
|
|
|
let articles = 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
|
|
|
|
}
|
|
|
|
return articles
|
2019-09-08 23:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|