【问题标题】:How can I remove duplicates from my list? [duplicate]如何从我的列表中删除重复项? [复制]
【发布时间】:2021-06-30 14:16:05
【问题描述】:

我正在使用 SwiftUI 在视图中生成这个动态列表(显示生成列表的一部分):

  • 薰衣草
  • 柠檬
  • 石灰
  • 石灰
  • 芒果

如何从列表中删除重复项(例如 LIME)?

这是我生成列表视图的代码:

struct FlavorGroupList: View {
    @ObservedObject private var viewModel = FlavorsViewModel()
    var body: some View {
        List(viewModel.flavors) { flavorListing in
            VStack(alignment: .leading) {
                Text(flavorListing.flavorGroup)
            }
        }
        .onAppear() {
            self.viewModel.fetchData()
        }
    }
}

这是我的视图模型代码:

class FlavorsViewModel: ObservableObject {
    @Published var flavors = [Flavor]()
    private var db = Firestore.firestore()
    func fetchData() {
        db.collection("flavors").order(by: "flavorGroup").addSnapshotListener { (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else {
                print("No documents")
                return
            }
            self.flavors = documents.compactMap { (queryDocumentSnapshot) -> Flavor? in
                return try? queryDocumentSnapshot.data(as: Flavor.self)
            }
        }
    }
}

这是我的型号代码:

struct Flavor: Identifiable, Codable {
    @DocumentID var id: String? = UUID().uuidString
    var code: String
    var descriptors: [String]
    var flavorGroup: String
    var keywords: [String]
    var legislation: String
    var name: String
}

我正在从 Firestore 数据库中导入数据。

提前感谢您提供的任何帮助。

【问题讨论】:

  • 你关心数组中元素的顺序吗?

标签: swift swiftui swiftui-list


【解决方案1】:

一种简单的方法是,先将数组flavors 转换为 Set,然后再将其转换回数组。

class FlavorsViewModel: ObservableObject {
    @Published var flavors = [Flavor]()
    private var db = Firestore.firestore()
    func fetchData() {
        db.collection("flavors").order(by: "flavorGroup").addSnapshotListener { (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else {
                print("No documents")
                return
            }
            self.flavors = documents.compactMap { (queryDocumentSnapshot) -> Flavor? in
                return try? queryDocumentSnapshot.data(as: Flavor.self)
            }
            self.flavors = Array(Set(flavors))//<- This line

        }
    }
}

参考文档:https://developer.apple.com/documentation/swift/set

【讨论】:

  • 这样做的一个潜在缺点是在转换为 Set 时会丢失元素的顺序。如果订单对您很重要,请改用 NSOrderedSet:Array(NSOrderedSet(array: flavors))
  • 我将尝试这种方法,并将很快对结果发表评论。
  • 我用这个类替换了我的视图模型类。重复项仍然出现在我的列表中。此处是否需要额外的代码来删除重复项?
  • 如果没有更多信息,我们只能猜测您的代码出了什么问题。那么您是否尝试过简化您的问题(例如,删除 firebase 功能并查看问题是否仍然存在)?
【解决方案2】:

您可以创建一个名为uniqueFlavor 空数组,循环检索检索到的风味,如果unique 阵列不存在,则使用contains(where: _) 将它们添加到数组中

func removeDuplicates() -> [Flavor] {
    var unique = [Flavor]()
    self.flavors.forEach { flavor in
        if !unique.contains(where: {$0.name == flavor.name}) {
            unique.append(flavor)
        }
    }
    return unique
}

【讨论】:

  • 我将尝试这种方法,并将很快对结果发表评论。
  • 这行得通,但 Array.contains 具有O(n) 性能。整个过程的性能将是O(n²),这对于除了非常小的数组之外的任何东西都非常糟糕。使用 NSOrderedSet 或数组作为输出加上临时的 Set 唯一性将为您提供 O(n) 性能。
  • 我添加了 removeDuplicates 函数,但我不知道如何/在哪里调用我的代码中的函数。
  • 你可以在self.flavors = documents.compactMap {...}闭包之后直接添加
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-07
  • 2011-02-20
  • 2014-09-30
相关资源
最近更新 更多