使用Firebase和Swift 3比较值的结构数据

时间:2017-06-16 00:11:11

标签: ios swift firebase firebase-realtime-database

我想知道我的数据结构方式是否是最好的方法。我之所以想知道这是因为我需要从数据中获得复杂的要求。

我正在尝试检查用户成分列表是否与食谱成分列表相匹配,并能够显示和计算它们。例如:

成分计数

1/2 ingredients

用户

Dough

用户没有

Mozzarella

我的食谱的数据结构目前如下所示:

{
  "RecipeData": {
    "-KlKMkBekJ6plrXI5cZV": {
      "name": "Pizza",
      "ingredients": {
        "-KkY8kL_wvxrcqMn_aP_": true,
        "-KkbS1pYW_9l4y4HPuog": true
      }
    }
  }
}

成分的详细信息,即 name 取自字典:

{
  "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类来处理配方中的属性:

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)"

1 个答案:

答案 0 :(得分:0)

由于额外的查找,它变成了一个嵌套练习。但如果你仔细阅读循环,它实际上并不是那么困难。在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

我在这里做的不同的关键是我首先假设用户没有必要的成分,然后如果结果他们已经有了这个成分那么就删除了这个假设