phparraysmultidimensional-arraycountarray-filter

Count "truthy" values in a 2d array


Given the following array $mm

Array
(
    [147] => Array
        (
            [pts_m] => 
            [pts_mreg] => 1
            [pts_cg] => 1
        )    
    [158] => Array
        (
            [pts_m] => 
            [pts_mreg] => 
            [pts_cg] => 0
        )

    [159] => Array
        (
            [pts_m] => 
            [pts_mreg] => 1
            [pts_cg] => 1
        )

)

When I run count(array_filter($mm)) I get 3 as result since it is not recursive.

count(array_filter($mm), COUNT_RECURSIVE) also will not do because I actually need to run the array_filter recursively, and then count its result.

So my question is: how do I recursively run array_filter($mm) in this case? My expected result here would be 4.

Please note that I am not using any callback so I can exclude false, null and empty.


Solution

  • Should work

    $count = array_sum(array_map(function ($item) {
      return ((int) !is_null($item['pts_m'])
           + ((int) !is_null($item['pts_mreg'])
           + ((int) !is_null($item['pts_cg']);
    }, $array);
    

    or maybe

    $count = array_sum(array_map(function ($item) {
      return array_sum(array_map('is_int', $item));
    }, $array);
    

    There are definitely many more possible solutions. If you want to use array_filter() (without callback) remember, that it treats 0 as false too and therefore it will remove any 0-value from the array.

    If you are using PHP in a pre-5.3 version, I would use a foreach-loop

    $count = 0;
    foreach ($array as $item) {
      $count += ((int) !is_null($item['pts_m'])
              + ((int) !is_null($item['pts_mreg'])
              + ((int) !is_null($item['pts_cg']);
    }
    

    Update

    Regarding the comment below:

    Thx @kc I actually want the method to remove false, 0, empty etc

    When this is really only, what you want, the solution is very simple too. But now I don't know, how to interpret

    My expected result here would be 5.

    Anyway, its short now :)

    $result = array_map('array_filter', $array);
    $count = array_map('count', $result);
    $countSum = array_sum($count);
    

    The resulting array looks like

    Array
    (
    [147] => Array
        (
            [pts_mreg] => 1
            [pts_cg] => 1
        )    
    [158] => Array
        (
        )
    
    [159] => Array
        (
            [pts_mreg] => 1
            [pts_cg] => 1
        )
    
    )