我有一個從使用結構的 firestore 填充的陣列。有沒有辦法計算 productName var 匹配字串的次數。
這是我的結構...
struct PlayerStock: Codable, Identifiable {
@DocumentID var id: String?
var productName: String
var qty: Int
var saleUID: String
var totalPrice: Int
var uid: String
var unitPrice: Int
}
這就是我的 VC 中的內容,我從 firestore 填充它,然后想計算 productName 中的匹配字串
var playerStock: [PlayerStock] = []
有沒有辦法在不使用 for 回圈的情況下做到這一點?
我想在 productName 中計算的字串包括"smartphone",或者"laptop"我想將匹配的總數存盤為這樣的 int:
var smartphoneTotal =
var laptopTotal =
etc etc..
我嘗試過使用過濾器和緊湊型地圖,但找不到任何有效的方法,我認為是因為陣列是多維的還是因為它使用了字典?
這里很菜鳥,所以任何幫助表示贊賞!
uj5u.com熱心網友回復:
首先對陣列進行分組productName
let groupedProducts = Dictionary.init(grouping: playerStock, by: \.productName)
你會得到
["smartphone":[PlayerStock(..), PlayerStock(..), PlayerStock(..)],
"laptop":[PlayerStock(..), PlayerStock(..)]
然后將值映射到它們的專案數量
.mapValues(\.count)
結果是
["smartphone":3, "laptop":2]
uj5u.com熱心網友回復:
如果你想使用過濾器,這樣的東西應該適用于你的結構:
var laptopTotal = playerStock.filter { $0.productName == "laptop" }.count
uj5u.com熱心網友回復:
這可能會有所幫助
let wordsToFind = ["smartphone", "laptop"]
var foundCounts: [String: Int] = [:]
for p in playerStock {
for word in wordsToFind {
if p.name.contains(word) {
foundCounts[word] = foundCounts[word, default: 0] 1
}
}
}
foundCounts
如果您真的想要一個功能性的“無 for 回圈”版本,并且您的意思是要查找包含搜索詞的內容,那么:
let wordsToFind = ["smartphone", "laptop"]
let founds = wordsToFind.map { word -> (String, Int) in
playerStock.reduce(("", 0)) { partialResult, player in
(word, partialResult.1 (player.name.contains(word) ? 1 : 0))
}
}
uj5u.com熱心網友回復:
您可以使用高階函式filter()或reduce(). @ShawnFrank 已經使用filter(). (已投票。)
對于少數專案,filter()和之間沒有太大區別reduce()。但是,對于大型資料集,過濾器會創建第二個陣列,其中包含與過濾器條件匹配的所有專案。陣列是值型別,因此它們保存它們所包含條目的副本。這將增加進行計數所需的記憶體占用。(您將擁有原始陣列和包含記憶體中所有匹配元素的副本)。
高階函式的reduce()作業方式不同。結果需要一個起始值(在我們的例子中是從 0 開始的總數)和一個閉包。閉包獲取當前結果,以及您正在決議的陣列中的一個元素。在運行時,該reduce()函式一遍又一遍地呼叫您的閉包,并從您正在減少的陣列中傳入每個元素。在對閉包的第一次呼叫中,它將結果的初始值發送給閉包(在我們的例子中,總數為零)。在對閉包的每個后續呼叫中,它都會傳遞上一次呼叫的結果。(運行總數,用于我們的實作。)該reduce()函式將最后一次呼叫回傳的結果回傳給您的閉包。
您可以使用reduce來計算與給定測驗匹配的專案數,而無需構建臨時陣列。下面是一個使用reduce(). 請注意,我調整了您的PlayerStock型別以添加??除 productName 以外的所有屬性的默認值,因為我不關心這些。
// Define the PlayerStock type, but use default values for everything but `productName`
struct PlayerStock: Codable, Identifiable {
var id: String? = nil
var productName: String
var qty: Int = Int.random(in: 1...10)
var saleUID: String = ""
var totalPrice: Int = Int.random(in: 10...200)
var uid: String = ""
var unitPrice: Int = Int.random(in: 10...200)
}
// Create an array of test data
let players = [
PlayerStock(productName: "smartphone"),
PlayerStock(productName: "CD Player"),
PlayerStock(productName: "laptop"),
PlayerStock(productName: "CD Player"),
PlayerStock(productName: "smartphone"),
PlayerStock(productName: "laptop"),
PlayerStock(productName: "smartphone"),
PlayerStock(productName: "boom box"),
PlayerStock(productName: "laptop"),
PlayerStock(productName: "smartphone"),
]
/// This is a function that counts and returns the number of PlayerStock items who's productName property matches a the string nameToFind.
/// If you pass in printResult = true, it logs its result for debugging.
/// - Parameter nameToFind: The `productName` to search for
/// - Parameter inArray: The array of `PlayerStock` items to search
/// - Parameter printResult: a debugging flag. If true, the function prints the count if items to the console. Defaults to `false`
/// - Returns: The number of `PlayerStock` items that have a `productName` == `nameToFind`
@discardableResult func countPlayers(nameToFind: String, inArray array: [PlayerStock], printResult: Bool = false) -> Int {
let count = array.reduce(0, { count, item in
item.productName == nameToFind ? count 1 : count
})
if printResult {
print("Found \(count) players with productName == \(nameToFind)")
}
return count
}
let smartphoneCount = countPlayers(nameToFind: "smartphone", inArray: players, printResult: true)
let laptopCount = countPlayers(nameToFind: "laptop", inArray: players, printResult: true)
let cdPlayerCount = countPlayers(nameToFind: "CD Player", inArray: players, printResult: true)
此示例代碼產生以下輸出:
Found 4 players with productName == smartphone
Found 3 players with productName == laptop
Found 2 players with productName == CD Player
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/454359.html
上一篇:從嵌套在陣列反應的物件中過濾陣列
