Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP Object-Oriented PHP Basics Building a Collection Shopping List Method

Darrell Conklin
Darrell Conklin
21,988 Points

Trying to wrap my head around this.

<?php

if (in_array($item."s", $ingredients)) {
          $item .= "s";
        } else if (in_array(substr($item, 0, -1), $ingredients)) {
          $item = substr($item, 0, -1);
        }

Having trouble wrapping my head around this part. Mainly the second half or it.

I don't understand how searching the array for the item string, with the last character cut off of it, will find the singular version if we've already eliminated the fact that there is no plural version with the first half of the conditional. Yet it worked for her.

I feel like I'm missing something here ... please help.

EDIT: My head tells me it will cut off the end of the already singular version.

7 Answers

Hamish Payne
Hamish Payne
8,666 Points

This section IS pretty confusing given that it has no effect on the ingredients list we are using! Had to look at it about five times! The $ingredients output is only changed by the ksort() function in the listShopping() method in render.php and the strstr() function in the getCombinedIngredients() method in recipecollection.php.

The first IF clause checks if we have already added the singular version of our ingredient to the $ingredients array; if we HAVEN'T then the ELSE IF clause check if we have already added the plural version of our ingredient (or our ingredient with an extra letter at the end) to the $ingredients array.

It won't cut a letter off as our 'haystack' is the $ingredients array we have just created in the getCombinedIngredients() method; not the original list of ingredients. However it is slightly flawed as it decides whichever version was added first is the right version.

Kaj, you're right it wouldn't work for plural forms that don't have an extra letter at the end but Alena says in the video "We'll assume it's an 's' " so I think she's just giving us examples of what can be done!

EDIT: Turns out this doesn't even work because in_array() can't find keys. As Maze pointed out in the other question on this video you should use array_key_exists()

I also found this particularly confusing for the exact same reason. An explanation of what happens as different strings come into this function would be helpful. For example:

onion onions

It has been over 3 weeks, bummer.

Alena Holligan
STAFF
Alena Holligan
Treehouse Teacher

This was a mistake in the video with the proper function call. I forgot that the ingredient itself was stored in the key of the array. I will try to get the video updated. For now the code sample in the notes is updated.

NOTE in_array vs array_key_exists

in_array will check the "value" in an array while array_key_exists will check the "key" in an array.

Code Sample

This code will NOT handle all plural vs singular ingredients, but this will get you started. You could be adding "es" or changing "y" to "ies".

public function getCombinedIngredients()
{
    $ingredients = array();
    foreach ($this->recipes as $recipe) {
        foreach ($recipe->getIngredients() as $i) {
            $item = $i['item'];
            if (strpos($item, ",")) {
                $item = strstr($item, ",", true);
            }
            if (array_key_exists($item . "s", $ingredients)) {
                $item .= "s";
            } else if (array_key_exists(substr($item,0,-1),$ingredients)) {
                $item = substr($ingredient,0,-1);
            }
            $ingredients[$item][] = array($i["amount"],$i["measure"]);
        }
    }
    return $ingredients;
}
Antonio De Rose
Antonio De Rose
20,884 Points

Could you send us the $ingredients array along with the $item variable.

Darrell Conklin
Darrell Conklin
21,988 Points

Here is a link to the workspace that contains all the code from the lesson. The code displayed above is taken from a class method called getCombinedIngredients on line 58 of recipecollection.php.

To better understand the concept of what's taking place here you can check the linked video at the top starting at 4:20

Hemen Nabi
Hemen Nabi
15,192 Points

It's confusing to me, as well. What happens to the words with identical singular and plural forms, like: fish, shrimp, salmon, etc. As pointed out by Darrell Conklin, won't the second half of the above code cut one letter off the end of such words?

Darrell Conklin I forked the workspace and there is still duplicates items.

IT RETURNS DUPLICATES

Egg
Eggs
Onion
Onions

INSTEAD OF ONLY

Eggs
Onions

TEACHERS CODE OUTPUT

[0] Belgian Waffles
[1] Ground Turkey Pepper Casserole
[2] Rabbit Catalan
[3] Spicy Omelette

SHOPPING LIST

Baking Powder
Bay Leaf
Bell Peppers
Blanched Almonds
Butter
Cheddar Cheese
Egg
Eggs
Flour
Garlic Cloves
Green Chili Pepper
Ground Turkey
Hazlenuts
Kielbasa Sausage
Milk
Olive Oil
Onion
Onions
Parsley
Pepper-Jack Cheese
Rabbit
Rabbit Stock
Raisins
Rice
Rosemary Spring
Saffron Threads
Salt
Salt & Pepper To Taste
Seasoned Flour
Sugar
Tomato Concasse
Tomato Sauce
Tomatoes
Vanilla
Xocolata A La Pedra