Все учебные пособия, которые я видел, были довольно «простой», когда дело доходит до сортировки и фильтрации, особенно при использовании SwiftData.
Я хотел включить не только сортировку по одному из атрибутов и прямую/обратную сортировку, но и также группирует данные.
Например, это код из проекта Earthquake от Apple (некоторые элементы удалены для краткости):
Код: Выделить всё
struct QuakeList: View {
@Environment(ViewModel.self) private var viewModel
@Environment(\.modelContext) private var modelContext
@Query private var quakes: [Quake]
init(
sortParameter: SortParameter = .time,
sortOrder: SortOrder = .reverse
) {
switch sortParameter {
case .time:
_quakes = Query(sort: \.time, order: sortOrder)
case .magnitude:
_quakes = Query(sort: \.magnitude, order: sortOrder)
}
}
Как я могу расширить это, чтобы оно также могло обрабатывать группировку, чтобы переменная Quakes действительно была многомерным массивом или даже словарем.
Для Например, я пытался сделать это для рендеринга:
Код: Выделить всё
enum GroupOption { // New grouping for Section
case time
case magnitude
case none
}
struct ListScreen: View {
@Environment(ViewModel.self) private var viewModel
@Environment(\.modelContext) private var modelContext
@Query private var quakes: [Quake]
@State private var groupedQuakes: [[Quake]] = [] // New multidimensional array
init(
sortParameter: SortParameter = .time,
sortOrder: ComparisonResult = .orderedAscending, // using ComparisonResult to store the enum value in defaults
sortGrouping: GroupOption = .none
) {
switch (sortParameter, sortOrder) {
case (.time, .orderedAscending):
_quakes = Query(sort: \.time, order: .forward)
case (.time, .orderedDescending):
_quakes = Query(sort: \.time, order: .reverse)
case (.magnitude, .orderedAscending):
_quakes = Query(sort: \.magnitude, order: .forward)
case (.magnitude, .orderedDescending):
_quakes = Query(sort: \.magnitude, order: .reverse)
default:
_quakes = Query(sort: \.time, order: .forward)
}
switch sortGrouping {
case .time:
groupedQuakes = Dictionary(grouping: _quakes.wrappedValue, by: { $0.time })
.sorted(by: { $0.key < $1.key })
.map({ $0.value })
case .magnitude:
groupedQuakes = Dictionary(grouping: _quakes.wrappedValue, by: { $0.magnitude })
.sorted(by: { $0.key < $1.key })
.map({ $0.value })
case .none:
groupedQuakes = [_quakes.wrappedValue]
}
}
Код: Выделить всё
// 1
List(quakes) { quake in
QuakeRow(quake: quake)
}
// 2
List {
ForEach(groupedQuakes, id: \.self) { group in
Section {
ForEach(group) { quake in
QuakeRow(quake: quake)
}
} header: {
groupHeader(for: group)
}
}
}
// ...
func groupHeader(for group: [Quake]) -> Text {
guard let group = group.first else { return Text("Unknown") }
switch groupOption {
case .time:
return Text(group.time.formatted(date: .numeric, time: .omitted))
case .magnitude:
return Text("\(group.magnitude)")
case .none:
return Text("All quakes")
}
}
Используя сортировку, включенную в тестовый проект Apple, землетрясения сортируются правильно.
Как только я пытаюсь добавить группировку и сортировку, эти данные возвращают пустые массивы.
Что-то я упускаю из виду?
Подробнее здесь: https://stackoverflow.com/questions/782 ... -swiftdata