How to add String values to an array of varying size?

8 views (last 30 days)
Hey I'm a begginner coding for a personal project. My problem right now is that I'm trying to assign string values into locations in an array that can change size. I have this "ingredient list" array set up as an anonymous function that changes size based on the number of ingredients. Next, there's if statements that find which meal (randomly decided in a previous function) I need to add ingredients for and then adds the specific ingredients to ingredient_list_lunches/dinners. I keep getting an error that says: "Unable to perform assignment because value of type 'string' is not convertible to 'function_handle'."
Here's the string array:
ingredients_list_tot = [("Steak"),("Broccoli"),("Carrot"),("Mushroom"),("Rice")...
("Teriyaki Sauce"),("Salmon"),("Bok Choy"),("Potato"),("Butter"),("Heavy Cream")...
("Nutella"),("Fruit"),("White Onion"),("Tomato"),("Lettuce"),("Carne Asada Seasoning"),...
("Pork"),("Chicken Broth"),("Bacon"),("Cabbage"),("Chicken"),...
("Tikka Masala"),("Naan"),("Lentils"),("Penn Pot Roast"),("Sausage"),...
("Shredded Cheese"),("Penne/Rotini"),("Garlic"),("Diced Tomatoes"),("Pasta Sauce"),...
("Black Beans"),("Carne Asada Seasoning"),("Meatballs"),("Cheese Slices"),("Bread"),...
("Canned Tomato Bisque"),("Canned Soup"),("Mac and Cheese"),("Hot Dogs"),("Frozen Fries"),...
("Fish Sticks"),("Chowder"),("Wontons"),("Flatbread")];
Here's my anonymous function:
ingredient_list_lunches = @(ing_tot_lunches) zeros([1 ing_tot_lunches]);
ing_tot_lunches = 0;
ingredient_list_dinners = @(ing_tot_dinners) zeros([1 ing_tot_dinners]);
ing_tot_dinners = 0;
And here's the code I'm using to add those strings to one list:
for idx = 1:numel(lunches)
if lunches(1,idx) == prep_meals_list(1,1) %TK Steak
ing_tot_lunches = ing_tot_lunches + 6;
ingredient_list_lunches(idx) = (ingredients_list_tot(1,1));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,2));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,3));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,4));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,5));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,6));
elseif lunches(1,idx) == prep_meals_list(1,2) %TK Salmon
ing_tot_lunches = ing_tot_lunches + 7;
ingredient_list_lunches(idx) = (ingredients_list_tot(1,7));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,8));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,4));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,3));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,2));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,5));
ingredient_list_lunches(idx) = (ingredients_list_tot(1,6));

Answers (2)

Cris LaPierre
Cris LaPierre on 20 Aug 2021
Edited: Cris LaPierre on 20 Aug 2021
I'm not sure I understand what you are trying to do with your anonymous functions.
The error here is because you define an anonymous function ingredient_list_lunches. However, you treat it like it is a variable, trying to assign it a value. It's like saying sin(5) = x when what you intend is x = sin(5).
As a function handle, you can use ingredient_list_lunches like you would any other function, calling it with inputs and capturing the outputs.
f = @(x) sin(x);
% works
y = f(pi/2)
y = 1
% does not work
f(1) = "5"
Unable to perform assignment because value of type 'string' is not convertible to 'function_handle'.

Caused by:
Error using function_handle
Too many output arguments.

Steven Lord
Steven Lord on 20 Aug 2021
A number of your variables are undefined, but I would consider one of two approaches. This approach, where recipe is a cell array of vectors of indices into the ingredients list, is pretty easy to define but vulnerable to adding new ingredients in the middle of the ingredients list.
ingredients_list_tot = [("Steak"),("Broccoli"),("Carrot"),("Mushroom"),("Rice")...
("Teriyaki Sauce"),("Salmon"),("Bok Choy"),("Potato"),("Butter"),("Heavy Cream")...
("Nutella"),("Fruit"),("White Onion"),("Tomato"),("Lettuce"),("Carne Asada Seasoning"),...
("Pork"),("Chicken Broth"),("Bacon"),("Cabbage"),("Chicken"),...
("Tikka Masala"),("Naan"),("Lentils"),("Penn Pot Roast"),("Sausage"),...
("Shredded Cheese"),("Penne/Rotini"),("Garlic"),("Diced Tomatoes"),("Pasta Sauce"),...
("Black Beans"),("Meatballs"),("Cheese Slices"),("Bread"),...
("Canned Tomato Bisque"),("Canned Soup"),("Mac and Cheese"),("Hot Dogs"),("Frozen Fries"),...
("Fish Sticks"),("Chowder"),("Wontons"),("Flatbread")];
% I trimmed the duplicate ("Carne Asada Seasoning")
recipe = {[1 2 6], ... % beef with broccoli
[15 16 20 35 36], ... % BLT with cheese
}
recipe = 1×2 cell array
{[1 2 6]} {[15 16 20 35 36]}
shoppingList = [ingredients_list_tot(recipe{1}), ingredients_list_tot{recipe{2}}].'
shoppingList = 8×1 string array
"Steak" "Broccoli" "Teriyaki Sauce" "Tomato" "Lettuce" "Bacon" "Cheese Slices" "Bread"
Alternately you might want to build a containers.Map or a table. This has the benefit of being able to specify dishes and/or ingredients in various orders and to use those names to update the recipes at the expense of taking up more room (number of ingredients times number of dishes, even if you only had two dishes that between them use only eight out of the 45 ingredients.
recipeTable = array2table(zeros(numel(ingredients_list_tot), 2), ...
'VariableNames', ["beef with broccoli", "BLT with cheese"], ...
'RowNames', ingredients_list_tot);
% Add recipes to the list
recipeTable{[1 2 6], "beef with broccoli"} = 1; % Steak, Broccoli, Teriyaki Sauce
recipeTable{["Tomato", "Lettuce", "Bacon", "Cheese Slices", "Bread"], 2} = 1; % BLT with cheese
% I'm including some ingredients not in either dish for demonstration of
% what the table looks like
disp(recipeTable([1 2 5 6 15 16 20 35 36 37], :))
beef with broccoli BLT with cheese __________________ _______________ Steak 1 0 Broccoli 1 0 Rice 0 0 Teriyaki Sauce 1 0 Tomato 0 1 Lettuce 0 1 Bacon 0 1 Cheese Slices 0 1 Bread 0 1 Canned Tomato Bisque 0 0
What do I need to make a BLT with cheese?
BLTCheese = recipeTable(recipeTable.("BLT with cheese") == 1, "BLT with cheese")
BLTCheese = 5×1 table
BLT with cheese _______________ Tomato 1 Lettuce 1 Bacon 1 Cheese Slices 1 Bread 1
shoppingList = BLTCheese.Properties.RowNames
shoppingList = 5×1 cell array
{'Tomato' } {'Lettuce' } {'Bacon' } {'Cheese Slices'} {'Bread' }

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!