swift 如何通过函数修改数组中的一个元素?[duplicate]

ovfsdjhp  于 2023-01-12  发布在  Swift
关注(0)|答案(1)|浏览(168)
    • 此问题在此处已有答案**:

Firestore query - array contains all(1个答案)
23小时前关门了。
我不确定这是不是最好的方法,但是当只放置一个常规数组时,我没有返回任何东西。
我在Swift中有一个类似这样的firebase集合:

struct Tournament: Identifiable, Codable, Equatable, Hashable {
    var playersUID: [String] = []  
}

我有一个UID数组,我想查询我的播放器文档

struct Player: Identifiable, Codable, Equatable, Hashable { }

我尝试将playersUID数组传递到searchPlayers()中,但我认为它不是获取每个值,而是尝试将整个数组传递到搜索函数中:

func searchPlayers() async {
    do {    
        let documents = try await Firestore.firestore().collection("Players")
            .whereField("playersUID", isGreaterThanOrEqualTo: tournament.playersUID). 
            .whereField("playersUID", isLessThanOrEqualTo: "\(tournament.playersUID)\u{f8ff}")
            .getDocuments()
            let player = try documents.documents.compactMap { doc -> Player? in
                try doc.data(as: Player.self)
            }
            await MainActor.run(body: {
               fetchedPlayers.append(contentsOf: player)
            })
    }

这是一种方法......我尝试的另一种方法是使用for循环:

do {
            let lastIndex = Int(tournament.playersUID.last!) ?? 0
            for i in 0...lastIndex {
                let documents = try await Firestore.firestore().collection("Players")
                    .whereField("playersUID", isGreaterThanOrEqualTo: tournament.playersUID[i])
                    .whereField("playersUID", isLessThanOrEqualTo: "\(tournament.playersUID[i])\u{f8ff}")
                    .getDocuments()
                
                let player = try documents.documents.compactMap { doc -> Player? in
                    try doc.data(as: Player.self)
                }
                
                await MainActor.run(body: {
                    fetchedPlayers.append(contentsOf: player)
                })
            }
            
            
        } catch {
            print(error.localizedDescription)
        }

我真的不知道我在这里做错了什么,是不是Firebase提供了一个独特的查询功能?

rdlzhqv9

rdlzhqv91#

您希望根据tournament.playersUID中存在的playerUIDs筛选集合,因此最佳实践是使用in、not-in和array-contains-any操作符来筛选数组字段的firestore集合。
for循环也不起作用,因为i变量是tournament.playersUID数组中某个特定元素的索引,而您仍在寻找精确匹配。
在我看来,有2种方法可以达到预期的结果:

  • 实现这一点的一种方法是使用whereField("playersUID", in: )whereField("playersUID", arrayContains: )方法,而不是whereField(“playersUID”,大于或等于:)和whereField(“playersUID”,小于或等于:):
func searchPlayers() async {
    do {
        let documents = try await Firestore.firestore().collection("Players")
            .whereField("playersUID", in: tournament.playersUID)
            .getDocuments() //arrayContainsAny can also be used if you want to achieve that behavior
        let player = try documents.documents.compactMap { doc -> Player? in
            try doc.data(as: Player.self)
        }
        await MainActor.run(body: {
            fetchedPlayers.append(contentsOf: player)
        })
    } catch {
        print(error.localizedDescription)
    }
}

这将返回“Players”集合中的所有文档,其中“playersUID”字段的值在tournament.playersUID数组中。

  • 下面的方法可能并不完美,因为我们在for循环中使用了await:
for uid in tournament.playersUID {
    let documents = try await Firestore.firestore().collection("Players")
        .whereField("playersUID", arrayContains: uid)
        .getDocuments()
    ...
}

它将过滤掉playersUID字段不包含数组中任何UID的所有玩家。

相关问题