1

I'm trying to figure out why my code is not returning the key associated with the value of an array. This program should compare the first letter of an item with an array in which the letters A-M are associated with a key of "1" and letters N-Z are associated with a key of "2" to indicate the aisle they would be located on. The most frequent error I'm getting is that the second parameter of the array_search is not an array, but I thought array_combine combined two arrays into a new array, thus ($aisles, $letters) should produce 1=>A, 1=>B and so on. The webpage form I'm using this on can be found at http://achamlin.gwiddle.co.uk/web182/Project3/HamlinProject3.php I keep getting the same output: "Banana is located on Aisle ." with no actual Aisle listed. Thanks for any help.

//create function to compare first letter of item to the aisle arrays
function checkAisle($term) {
    $item= "banana";
    $letters = array("A", "B", "C", "D", "E", "F", "G","H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T","U", "V", "W", "X", "Y", "Z");
    $aisles = array("1", "1", "1", "1", "1", "1", "1","1", "1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "2", "2","2", "2", "2", "2", "2", "2");$itemUC = UCfirst($item);
    $guide = array_combine($aisles, $letters);
    $itemUC = UCfirst($item);
    $firstChar = $itemUC[0];
    $location = array_search($firstChar, $guide);
    echo "$itemUC is located on Aisle $location.";
}           

//run function
checkAisle("banana");

4 Answers 4

3

I'm going to forgive the fact that you aren't using $term but $item inside your function (this may be a result of your attempts to self-solve, so I'll assume this to be fixed for my convenience)... Your code starts to go sour on the array_combine() line. If you call:

var_export($guide);

You will see:

array (
  1 => 'M',
  2 => 'Z',
)

This is because you have your key array and value array arguments reversed, the effect is that each subsequent value with a pre-existing key will overwrite the value (keys must be unique). Then if you try to lookup any letter that doesn't exist as a value in $guide you will receive false (boolean, not a string -- which echoes as a zero-length string) from array_search(). So your function will only work as intended on strings that begin with M or Z.

Anyhow, that's what's wrong. If you want to refine your code...

You only need to isolate and capitalize the first letter, then compare that character against the capital letter M.

Code: (Demo)

function checkAisle($term) {
    $location = ($itemUC = strtoupper($term[0])) < "M" ? 1 : 2;
    return "$itemUC is located on Aisle $location.";
}           

echo checkAisle("banana") , "\n";
echo checkAisle("guava") , "\n";
echo checkAisle("lemon") , "\n";
echo checkAisle("melon") , "\n";
echo checkAisle("nectarine") , "\n";
echo checkAisle("Trump");

Output:

B is located on Aisle 1.
G is located on Aisle 1.
L is located on Aisle 1.
M is located on Aisle 2.
N is located on Aisle 2.
T is located on Aisle 2.

Here is another version which incorporates a generated lookup array and a check that the first character is, in fact, a letter:

Code: (Demo)

function checkAisle($term) {
    if (!ctype_alpha($term[0])) {
        return "First character out of bounds";
    }
    $locations = array_fill_keys(range('A','L'),1)+array_fill_keys(range('M','Z'),2);
    $letter = strtoupper($term[0]);
    return "$letter is located on Aisle {$locations[$letter]}.";
}    

echo checkAisle("Trump") , "\n";
echo checkAisle("banana") , "\n";
echo checkAisle("melon") , "\n";
echo checkAisle("guava") , "\n";
echo checkAisle("nectarine") , "\n";
echo checkAisle("lemon") , "\n";
Sign up to request clarification or add additional context in comments.

6 Comments

@LawrenceCherone what am I missing? The OP says only 2 aisles, right? What order matters? I don't follow you. As far as I can tell, declaring all of that lookup array data is pure bloat. My answer performs with equal accuracy versus the OP's hardcoded arrays.
I'm really not following any of your points. I have proven my solution to be correct and accurate in my demo. I don't have any idea what you are talking about regarding order. Here is another demo with the function calls shuffled: 3v4l.org/YbZFl
now this one is pretty short! i like the comparison '< "M"'. the only issue with this solution is, that the function recognises invalid characters as isle 1.
@Bernard That is true. It is assumed that given the OP's hardcoded array, all values will start with a letter. Lawrence's answer will put 4banana and !banana in Aisle 1. I think this is beyond the question scope until the OP says otherwise.
I understand where you're coming from @mickmackusa but this is for a school project that required certain elements be present for full credit so unfortunately I need all the hardcoded arrays.
|
1

Because your assigning the $aisles array as the combined arrays keys and the $letters as the values, which you cant do so switch it and then just select out the array by the key/letter and it returns the aisle.

<?php
//create function to compare first letter of item to the aisle arrays
function checkAisle($item) {
    $letters = range('A', 'Z');
    $aisles = array("1", "1", "1", "1", "1", "1", "1","1", "1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "2", "2","2", "2", "2", "2", "2", "2");
    $guide = array_combine($letters, $aisles);
    $itemUC = ucfirst($item);
    $firstChar = $itemUC[0];
    echo "$itemUC is located on Aisle $guide[$firstChar].";
}           

//run function
checkAisle("banana");

https://3v4l.org/SddjA

Result:

Banana is located on Aisle 1.

Or a better way (handle errors), presuming you might want to add more aisles to your hardcoded array or letter A is actually in aisle 2 not 1.

<?php
//create function to compare first letter of item to the aisle arrays
function checkAisle($item = null) {
    // check param
    if (empty($item) || is_numeric($item)) {
        throw new InvalidArgumentException('Error: function checkAisle is expecting string');
    }

    // build data
    $letters = range('A', 'Z');
    $aisles = [
        "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
        "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2"
    ];
    $guide = array_combine($letters, $aisles);

    // 
    $itemUC = ucfirst($item);
    $firstChar = isset($itemUC[0]) ? $itemUC[0] : null;

    if (!isset($guide[$firstChar])) {
        return 'Item '.$itemUC.' not found in store.';
    }

    return $itemUC.' is located on Aisle '.$guide[$firstChar];
}           

//run function
try {
    echo checkAisle("banana").PHP_EOL;
    echo checkAisle("twix").PHP_EOL;
    echo checkAisle("-").PHP_EOL;

    echo checkAisle(123).PHP_EOL;
} catch (InvalidArgumentException $e) {
    echo $e->getMessage();
}

Comments

0
<?php
//create function to compare first letter of item to the aisle arrays
function checkAisle($term) {
    $item= "banana";
    $letters = array("A", "B", "C", "D", "E", "F", "G","H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T","U", "V", "W", "X", "Y", "Z");
    $aisles = array("1", "1", "1", "1", "1", "1", "1","1", "1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "2", "2","2", "2", "2", "2", "2", "2");
    $itemUC = UCfirst($item);
    $guide = array_combine($letters, $aisles);
    $itemUC = UCfirst($item);
    $firstChar = $itemUC[0];



    $location = $guide[$firstChar];


    echo "$itemUC is located on Aisle $location.";
}           

//run function
checkAisle("banana");

with array_combine, you have use the key 1 repeatedly and it overwrite all the other key.

Comments

0

Well, here is my solution. It will return 0, when there was not found a valid letter. And you can add multiple aisles easily.

  function checkAisle($name) {

   $letter = strtolower($name[0]);
   $result = 0; 

   if(in_array($letter, range('a', 'm'))){
    $result = 1; 
   }

   if(in_array($letter, range('n', 'z'))){
    $result = 2; 
   }

   // aisle 3, 4, 5, ... here

   return $result;

  }           

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.