[英]Structure data to compare values using Firebase with Swift 3
我想知道我的數據結構方式是否是最好的方法。 我之所以想知道這是因為我需要從數據中獲得復雜的要求。
我想,以檢查是否成分的用戶列表成分的配方列表相匹配,並能顯示和計數。 例如:
成分計數
1/2 ingredients
用戶有
Dough
用戶沒有
Mozzarella
我的食譜的數據結構目前如下所示:
{
"RecipeData": {
"-KlKMkBekJ6plrXI5cZV": {
"name": "Pizza",
"ingredients": {
"-KkY8kL_wvxrcqMn_aP_": true,
"-KkbS1pYW_9l4y4HPuog": true
}
}
}
}
成分的詳細信息,即名稱取自字典:
{
"IngredientData": {
"ingredients": {
"-KkbS1pYW_9l4y4HPuog": {
"name": "Dough"
},
"-KkY8kL_wvxrcqMn_aP_": {
"name": "Mozzarella"
}
}
}
}
以下是用戶添加自己的成分時的外觀:
{
"users": {
"Ss5XNpWJ5IfIuYiMqsxTnMgjNrm1": {
"usersList": {
"-KlKuq2xjbQcR3ZMsHF1": {
"name": "Dough"
}
}
}
}
}
通過這種數據結構,我發現很難將用戶成分列表的值與配方的成分列表進行比較。
我有一個Ingredient
類來處理用戶成分中的屬性,我也使用它來獲取配方中的成分名稱:
class Ingredient {
var name: String?
var key: String?
init(from snapshot: FIRDataSnapshot) {
let snapshotValue = snapshot.value as? [String: Any]
self.key = snapshot.key
self.ref = snapshot.ref
self.name = snapshotValue?["name"] as? String
}
我還有一個IngredientManager
,里面有我可以在任何地方調用的成分。
我有一個Recipe
類來處理Recipe
中的屬性:
class Recipe {
var name: String!
var ingredients = [String]()
var key: String
init(from snapshot: FIRDataSnapshot) {
let snapshotValue = snapshot.value as! [String: Any]
self.name = snapshotValue["name"] as? String
self.key = snapshot.key
recipeIng(snapshot: snapshot.childSnapshot(forPath: "ingredients"))
}
// Function to count the number of ingredients inside recipe... this works
func recipeIng(snapshot: FIRDataSnapshot) {
for item in snapshot.children {
guard let ing = item as? FIRDataSnapshot else { continue }
// Gets the key and turns it into a string and then appends it to the array.
guard let value = ing.key as? String else { return }
ingredients.append(value)
}
}
// Function to match the ingredients.
func matchedIngredients() -> ([String], [String]) {
var userHas = [String]()
var userHasNot = [String]()
// loops through the users ingredients
for ingedient in IngredientManager.shared.ingredients {
// loops through the recipe's ingredients
for i in ingredients {
if ingedient.name == r {
userHas.append(i)
} else {
userHasNot.append(i)
}
}
}
return (userHas, userHasNot)
}
}
我能夠計算食譜中的成分數量,但現在我正在努力將其與用戶的成分列表進行比較。 ingredient.name
能夠獲得用戶成分的名稱,這是我想用來比較它的用戶 ,因為用戶成分的關鍵與食譜完全不同。
這是我在標簽上顯示的方式:
ingredientLbl.text = "\(recipe.matchedIngredients().0.count)/\(recipe.ingredients.count)"
由於額外的查找,它變成了一個嵌套練習。 但是如果你讀完循環,實際上並不是那么困難。 在JavaScript中,這可以解決問題:
ref.child("users").once("value").then((usersSnapshot) => {
usersSnapshot.forEach((userSnapshot) => {
ref.child("RecipeData").once("value").then((recipesSnapshot) => {
recipesSnapshot.forEach((recipeSnapshot) => {
var userNeeds = [];
recipeSnapshot.child("ingredients").forEach((recipeIngredientSnapshot) => {
userNeeds.push(ingredientsData[recipeIngredientSnapshot.key].name); // assume the user needs this
var recipeIngredientName = ingredientsData[recipeIngredientSnapshot.key];
userSnapshot.child("usersList").forEach((userIngredientSnapshot) => {
var index = userNeeds.indexOf(userIngredientSnapshot.val().name)
if (index >= 0) {
userNeeds.splice(index, 1);
}
});
console.log("User "+userSnapshot.key+" "+(userNeeds.length?"cannot":"can")+" make "+recipeSnapshot.key+": missing ingredients "+userNeeds);
});
});
});
});
});
一個工作的jsbin: https ://jsbin.com/ziqobow/edit ? js,console
我有什么不同,這里的關鍵是,我首先假設用戶沒有必要每一個成分,然后如果事實證明他們確實已經有了成分去掉這個假設。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.