首页 > 解决方案 > ForEach 可识别结构对象属性到按类别名称排序的列表中

问题描述

我觉得我在这里遗漏了一些明显的东西,但是我已经坚持了几天,似乎找不到答案。

1.) 我正在使用一个单独的 swift 文件,该文件带有一个 Identifiable Struct,该文件具有一个具有 2 个 Struct 属性namecategoryName的对象。(旁注,我在对象中使用var而不是let,因为无法使用 .onMove 修饰符作为常量重新排列行)

    //STRUCT

struct Item: Identifiable {
    var id = UUID()
    var name: String
    var categoryName: String
}



//OBJECT

var items : [Item] = [

    //CLOTHING
    Item(name: "Hats", categoryName: "Clothing"),
    Item(name: "Shirts", categoryName: "Clothing"),
    Item(name: "Pants", categoryName: "Clothing"),

    //Electronics
    Item(name: "Macbook", categoryName: "Electronics"),
    Item(name: "Macbook Adapter", categoryName: "Electronics"),
    Item(name: "iPhone", categoryName: "Electronics"),


]

2.) 在一个 swiftui 文件中,我有这段代码来构建列表,使用嵌套的 ForEach 循环来提取 categoryName,将其添加到 Section 标题,然后再循环出项目。

    //List code

 NavigationView {
            List {
                ForEach(items) { currentItem in
                    Section(header: Text(currentItem.categoryName)){
                        ForEach(items) { currentItem in
                             NavigationLink(destination: ItemDetail(itemData: currentItem)){ ItemRow(item: currentItem)

                            }
                        }

不幸的是,我得到的是一个可笑的结果。

在此处输入图像描述

我在部分标题中获得了我的 categoryName,并在其下方列出了我的项目。实际上,我得到了它下面列出的所有项目,无论类别如何。然后以一种非常令人困惑的方式,这些部分将打印出与我的对象数组中的行完全相同的次数。

在这种情况下,我有 6 个,所以我得到 6 行。然而,在 2 个 categoryName 字符串“Clothing”和“Electronics”中,它们将分别打印 3 次。

感觉有一种简单的方法可以“为 items.categoryName 中的每个 categoryName 添加一个标题到该部分并列出相应的名称” - 但我没有破解这个。

希望这里有人能指出我做错了什么。

标签: structforeachswiftui

解决方案


你有一个平面数组,只是迭代了几次,所以结果也被平面乘了几次。

好的,对于您选择的模型,即items您尝试完成的结果可以通过以下方式达到...

List {
    ForEach(Array(Set(items.compactMap{ $0[keyPath: \.categoryName] })), id: \.self) { category in
        Section(header: Text(category)) {
            ForEach(items.filter { $0.categoryName == category }) { currentItem in
                 NavigationLink(destination: Text("ItemDetail(itemData: currentItem)")){ Text("\(currentItem.name)") }
                }
            }
        }
}
.listStyle(GroupedListStyle())

但是我会选择不同的模型items,即。字典为[categoryName: Item]


推荐阅读