0

I'm removing values from an array in PHP use an in_array check yet for some reason it does not want to check through the entire length of the exclude array. Running this code it removes the Dodge entries from the array but not the Toyota, why is this?

<?php

    $inventory = array(
        '0' => Array
            (
                'car_name' => 'Dodge',
                'set_name' => 'A',
                'edition' => 'B41',
                'location' => 'Houston'
            ),

        '1' => Array
            (
                'car_name' => 'Dodge',
                'set_name' => 'A',
                'edition' => 'B41',
                'location' => 'Houston'
            ),

        '2' => Array
            (
                'car_name' => 'Dodge',
                'set_name' => 'A',
                'edition' => 'B41',
                'location' => 'Houston'
            ),

        '3' => Array
            (
                'car_name' => 'Dodge',
                'set_name' => 'A',
                'edition' => 'VarA31',
                'location' => 'Houston'
            ),

        '4' => Array
            (
                'car_name' => 'Toyota',
                'set_name' => 'A',
                'edition' => 'VarA31',
                'location' => 'Houston'
            ),

        '5' => Array
            (
                'car_name' => 'Toyota',
                'set_name' => 'A',
                'edition' => 'VarA31',
                'location' => 'Houston'
            ),

        '6' => Array
            (
                'car_name' => 'Toyota',
                'set_name' => 'A',
                'edition' => 'VarA31',
                'location' => 'Houston'
            ),

        '7' => Array
            (
                'car_name' => 'Toyota',
                'set_name' => 'A',
                'edition' => 'VarA31',
                'location' => 'Houston'
            ),

        '8' => Array
            (
                'car_name' => 'Toyota',
                'set_name' => 'A',
                'edition' => 'VarA31',
                'location' => 'Houston'
            ),

        '9' => Array
            (
                'car_name' => 'Toyota',
                'set_name' => 'A',
                'edition' => 'VarA31',
                'location' => 'Houston'
            ),

        '10' => Array
            (
                'car_name' => 'Toyota',
                'set_name' => 'A',
                'edition' => 'VarA31',
                'location' => 'Houston'
            ),

        '11' => Array
            (
                'car_name' => 'Toyota',
                'set_name' => 'A',
                'edition' => 'VarA31',
                'location' => 'Houston'

            ),
    );

    $exclude = array('Dodge','Toyota');

    for($k=0; $k<sizeof($inventory); $k++)
    {
    if(in_array(trim($inventory[$k]['car_name']), $exclude))
    {   unset($inventory[$k]);}

    }

         $inventory = array_values($inventory);
         echo '<pre>';
         print_r($inventory);
         echo '</pre>';



    ?>
4
  • in_array() does not work on multidimensional arrays. Possible duplicate of this question Commented Dec 28, 2014 at 0:33
  • 4
    @user2058037 - in_array is being used on the $exclude array here, where it will work Commented Dec 28, 2014 at 0:34
  • 1
    This is a good example of why incremental for loops are not often used in languages supporting some kind of foreach construct. If you did this via foreach ($inventory as $k => $v) you'll find it much easier to manage. Commented Dec 28, 2014 at 0:41
  • think of it this way - if you have to "do a thing N times", use an incremental for loop. If you have to "do a thing to each element in a collection", choose a foreach instead. Commented Dec 28, 2014 at 0:43

3 Answers 3

1

Your problem is that unsetting an element from an enumerated array will adjust the size of your array, but testing using sizeof() to see if you should exit your loop, so each iteration where you unset will reduce the number of values left to test.

$exclude = array('Dodge','Toyota');

$size = sizeof($inventory);
for($k=0; $size; $k++) {
    if(in_array(trim($inventory[$k]['car_name']), $exclude)) {
        unset($inventory[$k]);
    }
}

$inventory = array_values($inventory);
echo '<pre>';
print_r($inventory);
echo '</pre>';
Sign up to request clarification or add additional context in comments.

Comments

1

You are removing the index:value pair from the array, while iterating it. So after unsetting a value the index positions dont match or even exist.

Try copying the values you do need, into a new empty array like this:

$exclude = array('Dodge','Toyota');
$filtered = array();

for($k=0; $k<sizeof($inventory); $k++){
    if(in_array(trim($inventory[$k]['car_name']), $exclude)){
        // dont do this because it is changing the count of elements in the array unset($inventory[$k]);
    } else {
        $filtered[] = $inventory[$k]; // push the desired values into a new array
    }
}

echo '<pre>';
print_r($filtered);  // this should have the values that don't have 'Dodge' or 'Toyota'
echo '</pre>';

Edit: Mark's answer would be the best way to go cause it is also better performance wise

3 Comments

Unsetting an array index in PHP has no effect on the numbers of subsequent indexes.
It's the sizeof() at fault.
yeah, after unsetting, the recalculation of sizeof() in the loop gets messed up
1

use foreach instead for($k=0; $k<sizeof($inventory); $k++):

foreach($inventory as $k => $row)

this is because while you are unsetting $inventory you skip elements

$k = 0, sizeof($inventory) = 12, you unset one of the items, $k++. $inventory[1] becomes $inventory[0]

$k = 1, sizeof($inventory) is now 11, you check $inventory[1] but not $inventory[0] (previous known as $inventory[1])

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.