I’m building a diet plan with Laravel 8.
Database looks like this:
Recipes | Category | Calories |
---|---|---|
Eggs | breakfast | 180 |
Yogourt | breakfast | 50 |
Apple pie | snacks | 289 |
Banana pie | snacks | 386 |
Tomato Pasta | lunch-dinner | 712 |
Chicken Salad | lunch-dinner | 956 |
Vegetables soup | lunch-dinner | 410 |
Fish with potatoes | lunch-dinner | 652 |
I’d like to get the day’s meals according to average daily calories.
For example, if my daily calories is 1500kcal, I want to get 4 recipes (breakfast/lunch/dinner/snacks) for the day whose total calories are between 1300-1500 calories.
I use the same category for lunch and dinner but I need 2 results from this category.
I built some functions to do this:
use AppModelsRecipe;
// Function to generate combinations of recipes
function generateCombinations($items, $n, $start = 0, $result = [], &$results = []) {
if ($n === 0) {
$results[] = $result;
return;
}
for ($i = $start; $i < count($items); $i++) {
$result[] = $items[$i];
generateCombinations($items, $n - 1, $i + 1, $result, $results);
array_pop($result);
}
}
// Function to filter combinations by total calories
function filterCombinationsByCalories($combinations, $dailyCaloriesMin, $dailyCalories) {
return array_filter($combinations, function($combination) use ($dailyCaloriesMin, $dailyCalories) {
$totalCalories = array_sum(array_column($combination, 'calories'));
return $totalCalories >= $dailyCaloriesMin && $totalCalories <= $dailyCalories;
});
}
// Function to get daily meal plan
function getDailyMealPlan($dailyCalories, $dailyCaloriesMin) {
$mealCategories = ['breakfast', 'lunch-dinner', 'snacks'];
$mealPlan = [];
foreach ($mealCategories as $category) {
$recipes = Recipe::where('meal', $category)->get()->toArray();
// Generate combinations of recipes for this meal category
$combinations = [];
if ($category == 'lunch-dinner') {
generateCombinations($recipes, 2, 0, [], $combinations);
} else {
generateCombinations($recipes, 1, 0, [], $combinations);
}
// Filter combinations by total calories
$filteredCombinations = filterCombinationsByCalories($combinations, $dailyCaloriesMin, $dailyCalories);
// If there are no valid combinations, choose a single recipe with the highest calories
if (empty($filteredCombinations)) {
$selectedRecipe = Recipe::where('meal', $category)->orderBy('calories', 'desc')->first();
$mealPlan[$category] = $selectedRecipe;
} else {
// Randomly select a combination from the filtered combinations
$selectedCombination = $filteredCombinations[array_rand($filteredCombinations)];
$mealPlan[$category] = $selectedCombination;
}
}
return $mealPlan;
}
But when I do:
$mealPlan = getDailyMealPlan($dailyCalories, $dailyCaloriesMin);
dd($mealPlan);
I get an Object for breakfast
, an Object for snacks
and one Array with 2 results for lunch-dinner
See here:
array:3 [▼
"breakfast" => AppModelsRecipe {#1388 ▶}
"lunch-dinner" => array:2 [▶]
"snacks" => AppModelsRecipe {#1736 ▶}
]
I don’t understand why I don’t get 3 Array. I would like to obtain this result:
array:3 [▼
"breakfast" => array:1 [▶]
"lunch-dinner" => array:2 [▶]
"snacks" => array:1 [▶]
]
Any solution?