这是一个使用 cmets 的工作示例。我还把你的代码收紧了一点。
struct SectionsFromArrayView: View {
@State private var listeDeLieux: [Lieu] = Lieu.previewData
private var lieuxParTag: [String: [Lieu]] {
// This first loop extracts the different tags from the array into a set
// to unique them so we only iterate each tag once in the next step.
var tagSet: Set<String> = []
for lieu in listeDeLieux {
for tag in lieu.tags {
tagSet.insert(tag)
}
}
// This loop puts together the dictionary by filtering listeDeLieux by tag
var parTag: [String: [Lieu]] = [:]
for tag in Array(tagSet).sorted() {
let lieuArray = listeDeLieux.filter( { $0.tags.contains(tag) })
parTag[tag] = lieuArray
}
return parTag
}
var body: some View {
List {
// Instead of having a separate computed variable lieuxTags, you can sort the
// array of the lieuxParTag.keys
ForEach(lieuxParTag.keys.sorted(by: <), id: \ .self) {tag in
Section(header: Text (tag)) {
ScrollView(.horizontal, showsIndicators: true) {
LazyHStack {
ForEach(lieuxParTag[tag]!) { lieu in
Text (lieu.nom)
}
}
}
}
}
}
}
}
struct Lieu: Identifiable, Hashable {
var id = UUID().uuidString
var nom: String
var dateAjout = Date()
var img: String
// By making tags a set, they are uniqued
var tags: Set<String>
static var previewData: [Lieu] = [
Lieu(nom: "Alfred", img: "pencil", tags: ["pencil", "doc"]),
Lieu(nom: "Ben", img: "pencil", tags: ["pencil"]),
Lieu(nom: "Charles", img: "paperplane", tags: ["paperplane", "doc"]),
Lieu(nom: "Alfred", img: "paperplane", tags: ["paperplane"]),
Lieu(nom: "Alfred", img: "pencil", tags: ["pencil", "doc"])
]
}
如果你可以让你的标签成为一个枚举,你可以进一步压缩代码,因为你已经有了你的有限集合。这进一步缩小了 lieuxParTag:
struct SectionsFromArrayView: View {
@State private var listeDeLieux: [Lieu] = Lieu.previewData
private var lieuxParTag: [Tag: [Lieu]] {
var parTag: [Tag: [Lieu]] = [:]
// In order to get an array, Tag.allCases, Tag must conform to CaseIterable
for tag in Tag.allCases {
let lieuArray = listeDeLieux.filter( { $0.tags.contains(tag) })
parTag[tag] = lieuArray
}
return parTag
}
var body: some View {
List {
// In order to sort the keys, Tag must conform to Comparable
ForEach (lieuxParTag.keys.sorted(), id: \ .self) {tag in
Section(header: Text(tag.rawValue)) {
ScrollView(.horizontal, showsIndicators: true) {
LazyHStack {
ForEach(lieuxParTag[tag]!) { lieu in
Text(lieu.nom) + Text(Image(systemName: lieu.img))
}
}
}
}
}
}
}
}
struct Lieu: Identifiable, Hashable {
var id = UUID().uuidString
var nom: String
var dateAjout = Date()
var img: String
// By making tags a set, they are uniqued
var tags: Set<Tag>
static var previewData: [Lieu] = [
Lieu(nom: "Alfred", img: Tag.pencil.rawValue, tags: [.pencil, .doc]),
Lieu(nom: "Ben", img: Tag.pencil.rawValue, tags: [.pencil]),
Lieu(nom: "Charles", img: Tag.paperplane.rawValue, tags: [.paperplane, .doc]),
Lieu(nom: "Alfred", img: Tag.paperplane.rawValue, tags: [.paperplane]),
Lieu(nom: "Alfred", img: Tag.pencil.rawValue, tags: [.pencil, .doc])
]
}
enum Tag: String, CaseIterable, Comparable {
case doc, paperplane, pencil
static func < (lhs: Tag, rhs: Tag) -> Bool {
lhs.rawValue < rhs.rawValue
}
}