Я создал Minimal, полный и проверяемый пример (MCVE) из исходного кода, и я сделал его работу в Swift 3 детской площадки
import UIKit
import XCTest
extension Date
{
init?(year: Int, month: Int, day: Int) {
var dateComponents = DateComponents()
dateComponents.day = day
dateComponents.month = month
dateComponents.year = year
guard let date = Calendar.current.date(from: dateComponents)
else { return nil }
self = date
}
}
struct MyObject {
var created: Date
}
protocol MyProtocol {
var myArray: [MyObject] { get set }
}
extension MyProtocol {
mutating func sortArrayByCreationTime() {
myArray.sort {
$0.created > $1.created
}
}
}
struct ArrayContainer: MyProtocol {
var myArray: [MyObject]
}
let objects = [
MyObject(created: Date(year: 2016, month: 9, day: 1)!),
MyObject(created: Date(year: 2016, month: 11, day: 1)!),
MyObject(created: Date(year: 2016, month: 4, day: 1)!),
MyObject(created: Date(year: 2016, month: 8, day: 1)!),
]
var container = ArrayContainer(myArray: objects)
var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMdd"
XCTAssertEqual(["0901", "1101", "0401", "0801"],
container.myArray.map { dateFormatter.string(from: $0.created) })
container.sortArrayByCreationTime()
XCTAssertEqual(["1101", "0901", "0801", "0401"],
container.myArray.map { dateFormatter.string(from: $0.created) })
Позволь мне привести два варианта:
Вариант 1: Улучшение
В варианте 1, расширить массив-структуру, так что вы можете создать метод sortByCreationDate
мутирует. Существует трюк, который должен быть вытащил из шляпы, чтобы продлить [MyObject] (массив MyObject)
protocol MyObjectProtocol { var created: Date { get set } }
extension MyObject: MyObjectProtocol { }
extension Array where Element: MyObjectProtocol {
mutating func sortByCreationTime() {
self.sort {
$0.created > $1.created
}
}
}
var container2 = ArrayContainer(myArray: objects)
XCTAssertEqual(["0901", "1101", "0401", "0801"],
container2.myArray.map { dateFormatter.string(from: $0.created) })
container2.myArray.sortByCreationTime()
XCTAssertEqual(["1101", "0901", "0801", "0401"],
container2.myArray.map { dateFormatter.string(from: $0.created) })
Вариант 2: Лучше
В варианте 2, продлить последовательность. Последовательность позволит вам сортировать объекты, которые являются массивами, и другими типами, например, словарями. Тем не менее, он не создает мутирующий метод. Но, честно говоря, MyProtocol
- это запутанный API. С помощью этого метода MyProtocol
больше не требуется.
extension Sequence where Iterator.Element == MyObject {
func sortedByCreationTime() -> [Iterator.Element] {
return self.sorted {
$0.created > $1.created
}
}
}
var container3 = ArrayContainer(myArray: objects)
XCTAssertEqual(["0901", "1101", "0401", "0801"],
container3.myArray.map { dateFormatter.string(from: $0.created) })
XCTAssertEqual(["1101", "0901", "0801", "0401"],
container3.myArray.sortedByCreationTime().map { dateFormatter.string(from: $0.created) })
Ваш код никогда не собирается компилироваться в его нынешнем виде, потому что какая гарантия имеет компилятор, что элемент массива имеет свойство 'created'? – matt
@matt По-видимому, компилятор может вывести свойство 'created' из' MyObject'. – vadian
@vadian Моя точка зрения заключается в том, что OP должен был показать MyObject как часть вопроса. Для MCVE требуется достаточно кода для компиляции. – matt