0

In the following code I have two arrays $x and $m. I then mapped the two arrays as $k but what I want is that after the two arrays are mapped, if there is an empty element on either of the array $x and $m ($x in this case) then it needs to filter out the corresponding mapped elements from $k as well which is the mapped array.

<!DOCTYPE html>
<html>
<body>
<?php  
$x = array("apple", "", 2, null, -5, "orange", 10, false, "",22);
var_dump(array_filter($x));
echo "<br/>";
$m = [12,13,14,15,16,17,18,19,20,21];

$k = array_map(null, $x, $m);
array_filter($k);
shuffle($k);

$count = 1;
foreach ($k as $a) { 
if($count <= 8){  
echo "The number is: $a[0]. $a[1]. <br>";
 }else{
 break;
 }
   $count++; 
}
?>  
</body>
</html>

But this doesn't seem to work. The output I get is the following:

array(6) { [0]=> string(5) "apple" [2]=> int(2) [4]=> int(-5) [5]=> string(6) "orange" [6]=> int(10) [9]=> int(22) } 
The number is: . 19.
The number is: -5. 16.
The number is: apple. 12.
The number is: 22. 21.
The number is: . 20.
The number is: . 15.
The number is: . 13.
The number is: 2. 14.

What I want is that . 20 or . 15 etc be filtered out. How do I go about solving this?

1
  • 2
    array_filter returns a new, filtered array. It doesn't modify the original array. Use it akin to array_map, not akin to shuffle. Commented Oct 13, 2020 at 11:37

2 Answers 2

1

As noticed in comments - array_filter does not modify the array, instead - it returns new array, so your code can be rewritten as:

<?php  
$x = array("apple", "", 2, null, -5, "orange", 10, false, "",22);
$filteredX = array_filter($x);

var_dump($filteredX);

echo "<br/>";

$m = [12,13,14,15,16,17,18,19,20,21];

$k = array_map(null, $filteredX, $m);
$filteredK = array_filter($k);
shuffle($filteredK);

$count = 1;
foreach ($filteredK as $a) { 
if($count <= 8){  
echo "The number is: $a[0]. $a[1]. <br>";
 }else{
 break;
 }
   $count++; 
}
?>

But! As array_map with null callback returns array of arrays, array_filter does not filter elements that have both elements not empty.

What shows print_r($k) (excerpt):

Array
(
    [0] => Array
        (
            [0] => apple
            [1] => 12
        )

    [1] => Array
        (
            [0] => 2
            [1] => 13
        )

    [2] => Array
        (
            [0] => -5
            [1] => 14
        )

    [3] => Array
        (
            [0] => orange
            [1] => 15
        )

    [4] => Array
        (
            [0] => 10
            [1] => 16
        )

    [5] => Array
        (
            [0] => 22
            [1] => 17
        )

    [6] => Array
        (
            [0] => 
            [1] => 18
        )

    [7] => Array
        (
            [0] => 
            [1] => 19
        )

As you can see, elements under indices 6,7 and more have empty value under key [0]. As array_filter filters only plain values, to clear your array from subarrays with empty first element, you should use array_filter with a callback:

$k = array_map(null, $filteredX, $m);
$filteredK = array_filter($k, function($v) { return isset($v[0], $v[1]);});
shuffle($filteredK);

After this filtering you will not get empty values. Final fiddle here.

Sign up to request clarification or add additional context in comments.

4 Comments

But once you filter out the array with empty values $x here, that implies that the filtered array will map to the none filtered one $m in this case. When I run this code for example what I also got is that 2 from $x is mapped to 13 from $m which is not what i want. I want both 2 and empty string from $m be filtered out. Not one of them be mapped to the other element
Sorry, I don't get what you mean.
I meant when I open the final fiddle of the code, I get -5 from array $x matched with 14 from array $m in the output. But according to the original array i want -5 from array $x to match with 16 from array $m. In the solution you gave $filteredX = array_filter($x); is done in the very beginning. That will filter the array and then map it.
So, don't use first array_filter then.
0
    $x = array("apple", "", 2, null, -5, "orange", 10, false, "",22);
    array_filter($x);
    echo "<br/>";
    $m = [12,13,14,15,16,17,18,19,20,21];

    $k = array_map(null, $x, $m);

    /* This is the filter code */
    $k = array_filter($k, function($value) {
        return (bool) $value[0] && (bool) $value[1];
    });
    /***************************/

    shuffle($k);

    $count = 1;
    foreach ($k as $a) {
        if($count <= 8){
            echo "The number is: $a[0]. $a[1]. <br>";
        }else{
            break;
        }
        $count++;
    }

3 Comments

You're welcome! I hope you understand how it works, please vote for my answer, thank you!
Hey, yeah i think i understood the code. Thanks again.
Great, please mark the answer as correct for this question, thanks.

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.