У меня есть 2 вида struct, Header
и Session
, оба соответствуют протоколу TimelineItem
.
У меня есть Array
состоит из TimelineItem
так:
[Header1, SessionA, SessionB, Header2, SessionC, SessionD]
Swift: преобразование массива [A, B, B, B, A, B, B, B] в массив хэш [[A: [B, B, B], [A: [B, B, B ]]]
Моей потребности в группу Session
под соответствующей Header
, как это:
[ [Header1: [SessionA, SessionB], [Header2: [SessionC, SessionD] ]
Я попытался с помощью filter
метода для получения только Header
-структуры, и split
метод для извлечения массива Session
Массив. Они работают нормально, но я не могу справиться с тем, как согласовать оба, чтобы построить мой последний объект [[Header: [Session]]]
.
Вот мой пример кода:
enum TimelineItemType: String {
case Header = "header"
case Session = "session"
}
protocol TimelineItem {
var id: Int { get }
var type: TimelineItemType { get }
var startDate: NSDate { get }
}
Header
структура
struct Header: TimelineItem, Decodable, Hashable, Equatable {
let id: Int
let type: TimelineItemType = .Header
let startDate: NSDate
let text: String
init?(json: JSON) {
guard let id: Int = "id" <~~ json,
let type: TimelineItemType = "type" <~~ json,
let startDate: NSDate = "startDate" <~~ json,
let text: String = "text" <~~ json where type == .Header else {
return nil
}
self.id = id
self.startDate = startDate
self.text = text
}
var hashValue: Int {
// As id is unique, we can use it for hash purpose
return id
}
}
Session
структура
struct Session: TimelineItem, Decodable, Equatable {
let id: Int
let type: TimelineItemType = .Session
let startDate: NSDate
let name: String
let syllabus: String
let speaker: Speaker
let language: String
let room: String
let duration: Int
init?(json: JSON) {
guard let id: Int = "id" <~~ json,
let type: TimelineItemType = "type" <~~ json,
let startDate: NSDate = Decoder.decodeDateISO8601("startDate")(json),
let name: String = "name" <~~ json,
let speaker: Speaker = "speaker" <~~ json,
let syllabus: String = "syllabus" <~~ json,
let language: String = "language" <~~ json,
let room: String = "room" <~~ json,
let duration: Int = "duration" <~~ json where type == .Session else {
return nil
}
self.id = id
self.startDate = startDate
self.name = name
self.speaker = speaker
self.syllabus = syllabus
self.language = language
self.room = room
self.duration = duration
}
}
И, наконец, код, который я пытался разделить мой массив:
func timelineFromItems(timelineItems: [TimelineItem]) -> [[Header: [Session]]]? {
let slicedSessions = timelineItems.split { $0 is Header }
let sessions = Array(slicedSessions)
let headers = timelineItems.filter { $0.type == .Header }
var timeline = [[Header: [Session]]]()
// HOW TO FILL THE TIMELINE ??
}
КАК ЗАПОЛНИТЬ ВРЕМЯ?
Существует недостающее открытие' { 'в' for' заявлении. – Gl0ub1l
Спасибо за исправление, я отредактировал ответ –
Juste попробовал ваше решение, которое кажется действительно закрытым для того, что я хотел бы иметь. Но у меня есть ошибка компиляции: «Неоднозначная ссылка на индекс» в 'session [index]'. – Gl0ub1l