phparraysfilterarray-difference

Corrupted output when printing array_diff() results with a for() loop


I have seen some similar issues here but could not get an answer to my problem.

I am using the array_diff() function to take the difference of two arrays, but it does not work as expected. Here is my code.

$quals = ['TeamA', 'TeamB', 'TeamC', 'TeamD', 'TeamE', 'TeamF', 'TeamG', 'TeamH', 'TeamI', 'TeamJ', 'TeamK', 'TeamL'];
$assigned = ['', '', 'TeamE', 'TeamF', '', '', 'TeamD', 'TeamH','', '', '', 'TeamG'];

for ($i = 0; $i < count($quals); $i++)
    echo $quals[$i] . '-';
echo count($quals);

echo "<br>";

for ($i = 0; $i < count($assigned); $i++)
    echo $assigned[$i] . '-';
echo count($assigned);

echo "<br>";  

$remainings = array_diff($quals, $assigned);
for ($i = 0; $i < count($remainings); $i++)
    echo $remainings[$i] . '-';
echo count($remainings);

This is what I get as the output:

TeamA-TeamB-TeamC-TeamD-TeamE-TeamF-TeamG-TeamH-TeamI-TeamJ-TeamK-TeamL-12

--TeamE-TeamF---TeamD-TeamH----TeamG-12

TeamA-TeamB-TeamC-----7

What I would expect in the last line is:

TeamA-TeamB-TeamC-TeamI-TeamJ-TeamK-TeamL-7

Why am I getting these consecutive hyphens? And why are four of the elements missing when printing the hyphenate string?


Solution

  • you are getting those because array_diff retains the original keys from the first array

    so your $remainings array looks like this

    Array ( 
       [0] => TeamA 
       [1] => TeamB 
       [2] => TeamC 
       [8] => TeamI 
       [9] => TeamJ 
       [10] => TeamK 
       [11] => TeamL 
    )
    

    Notice the 8,9,10,11 indexes for the last half of the team names

    so when you were doing the for loop you had the index going from 0 to 7, and since there is no 3,4,5,6 indexes nothing was being printed (you would have gotten an E_NOTICE undefined index error if you had display_errors on)

    so instead of doing the regular for loop use a foreach loop

    foreach($remainings as $team)
      echo $team.'-';
    echo count($remainings);
    

    will output: TeamA-TeamB-TeamC-TeamI-TeamJ-TeamK-TeamL-7

    PHPFiddle Demo (hit the run button)

    As Niet the Dark Absol mentions you can also just use array_values to "reset" the keys just do the following:

    $remainings = array_values( array_diff($quals,$assigned) );
    

    http://php.net/array-values

    array_values() returns all the values from the array and indexes the array numerically.