skip to Main Content

I need a multidimensional array/list (2 and/or 3 dimensions) which must contains different objects.
This is what I found:

  List recipes = List.generate(
      999,
      (_) => List<Ingredient>.filled(
          9,
          Ingredient(
              name: '', carboidrates: 0, proteins: 0, lipids: 0, fibers: 0),
          growable: true));

My needs is to have recipes[index/int][index/Ingredient].somethingoftheIngredientClass

As for example, if I create a single List:

List<Ingredient> recipe = <Ingredient>[];

I can access the class as

recipe[0].carboidrates

Not the same for my 2 dimensional list:

recipes[0][0].doesnotshowCarboidrates

3

Answers


  1. Chosen as BEST ANSWER

    Just found a programming 'bug'.

    I tried to replicate my exactly code:

      List recipes = List.generate(
          999,
          (_) => List<Ingredient>.filled(
              9,
              Ingredient(
                  name: 'Cheesecake',
                  carboidrates: 0,
                  proteins: 0,
                  lipids: 0,
                  fibers: 0),
              growable: true));
    

    As you can see by adding 'Cheesecake' as the name.

    In Init functions I just tried this:

    print(recipes[0][0].name);
    

    This work as expected, I accessed the value correctly...

    Console Output:

    Restarted application in 262ms.
    flutter: Cheesecake
    

    Really don't know why when I arrive at this point:

    print(recipes[0][0].
    

    Visual Studio Code does not show Class/Ingredient properties*, however it works!

    *It shows only:

    hashCode, runtimeType, toString(), noSuchMethod(...)
    

    Really hope someone should explain why...


  2. A list or multi-dimensional lists can only have a single type. Looking at your sample code, it looks like you’re trying to associate ingredients and properties of a given recipe to a recipe using a multi-dimensional list.

    A better approach would be to use classes. Classes will give you a more structured design and a little more flexibility. For example, the code below overrides the equality operator (==) and hashCode to be able to compare recipes and find a given recipe in a list.

    
    class Recipe {
      final String name;
      final List<Ingredient> ingredients;
      final List<Instruction> instructions;
    
      Recipe({
        required this.name,
        required this.ingredients,
        required this.instructions,
      });
    
      @override
      bool operator ==(Object other) =>
          identical(this, other) || other is Recipe && runtimeType == other.runtimeType && name == other.name;
    
      @override
      int get hashCode => name.hashCode ^ ingredients.hashCode ^ instructions.hashCode;
    }
    
    class Ingredient {
      final String name;
      final String description;
    
      Ingredient({
        required this.name,
        required this.description,
      });
    }
    
    class Instruction {
      final String description;
      final String? tip;
    
      Instruction({
        required this.description,
        this.tip,
      });
    }
    
    final recipes = [
      Recipe(
        name: 'Cheese pizza',
        ingredients: [
          Ingredient(name: 'Dough', description: 'Normal yeast based pizza dough'),
          Ingredient(name: 'Tomato Sauce', description: 'Freshly blended organic tomatoes'),
          Ingredient(name: 'Mozzarella Cheese', description: 'Cheesy cheesiness from mount cheese'),
        ],
        instructions: [
          Instruction(description: 'Preheat oven to 400 degrees Fahrenheit'),
          Instruction(description: 'While oven is preheating spread dough evenly in a circle over an oiled pan'),
          Instruction(description: 'Spread sauce evenly over dough leaving enough room for the crust'),
          Instruction(description: 'Cover the sauce with the Mozzarella cheese'),
          Instruction(
            description: 'Roll the edge of the dough to form the crust',
            tip: 'Optionally add cheese within the dough for stuffed crust!',
          ),
          Instruction(description: 'Bake the pizza in the over until golden brown'),
          Instruction(
            description: 'Remove the pizza from the oven and let cool',
            tip: 'Some people like to let the pizza cool before cutting',
          ),
        ],
      ),
    ];
    
    /// Find the index of a recipe. This uses the equality and hashcode overrides of the recipe class.
    int getRecipeIndex(Recipe recipe) => recipes.indexOf(recipe);
    
    /// Find all of the recipes containing the [query] in their name (case-insensitive).
    List<Recipe> getRecipeByName(String query) {
      return recipes.where((element) => element.name.toLowerCase().contains(query.toLowerCase())).toList();
    }
    
    /// Get the ingredients of a recipe.
    final recipeIngredients = recipes[0].ingredients;
    
    /// Get the instructions of a recipe.
    final recipeInstructions = recipes[0].instructions;
    
    /// Get a list of all of the tips for a recipe.
    final recipeTips = recipes[0].instructions.map((e) => e.tip).whereType<String>();
    

    If for whatever reason you wanted to associate a recipe with a list of recipes (e.g. similar recipes) I would use a map of Recipe to List<Recipe>.

    final pizza = recipes[0];
    
    /// How to associate a recipe with similar recipes using a map of `Recipe` to `List<Recipe>`
    final similarRecipesMap = { pizza: [recipes[1], recipes[2]]};
    
    final similarRecipesToPizza = similarRecipesMap[pizza];
    

    Hope that helps!

    Login or Signup to reply.
  3. Yup, another practical way to have 2d/3d list:

    eg a 3d example:

      List<List<List<Ingredient>>> ingredient =
          List.generate(999, (index) => [[]], growable: true);
    

    On Init function:

    ingredient[0][0].clear();
    ingredient[0][0].add(Ingredient(
        name: 'Panettone', carboidrates: 0, proteins: 0, lipids: 0, fibers: 0));
    print(ingredient[0][0][0].name);
    

    And now when I arrive here:

    print(ingredient[0][0][0].
    

    I finally should see the Ingredient Class properties (like name, carboidrates… and so on!)… WIN!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search