Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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.

share|improve this question
1  
Are you simply trying to count the array elements that have a value? – Jrod Jul 22 '11 at 20:21
@jrod that's correct, but not 0 – torr Jul 22 '11 at 20:31
add comment (requires an account with 50 reputation)

3 Answers

up vote 2 down vote accepted

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
    )

)
share|improve this answer
Thx @kc I actually want the method to remove false, 0, empty etc – torr Jul 22 '11 at 20:37
Your statement "My expected result here would be 5." is quite misleading then and after remove any false-evaluated value count($array) will still not return 0. – KingCrunch Jul 22 '11 at 20:42
"... still not return 5". It counts the elements of the array and an array is an element and therefore will get counted as 1 (I just don't wanted this comment to be a silly "want to fix my typo"..) – KingCrunch Jul 22 '11 at 20:49
thanks a lot @kingcrunch -- your suggestion works beautifully, much appreciated! – torr Jul 23 '11 at 3:35
add comment (requires an account with 50 reputation)

From the PHP array_filter documentation:

//This function filters an array and remove all null values recursively. 

<?php 
  function array_filter_recursive($input) 
  { 
    foreach ($input as &$value) 
    { 
      if (is_array($value)) 
      { 
        $value = array_filter_recursive($value); 
      } 
    } 

    return array_filter($input); 
  } 
?> 

//Or with callback parameter (not tested) : 

<?php 
  function array_filter_recursive($input, $callback = null) 
  { 
    foreach ($input as &$value) 
    { 
      if (is_array($value)) 
      { 
        $value = array_filter_recursive($value, $callback); 
      } 
    } 

    return array_filter($input, $callback); 
  } 
?>
share|improve this answer
would this also remove empty and 0? – torr Jul 22 '11 at 20:36
@torr - This would work the same way as array_filter normally does. If you look in the function, it calls array_filter unless it's the current value is an array at which point it calls the array_filter_recursive function. – Francois Deschenes Jul 22 '11 at 20:39
add comment (requires an account with 50 reputation)
<?php

$mm = array
(
    147 => array
        (
            "pts_m" => "",
            "pts_mreg" => 1,
            "pts_cg" => 1
        ) ,
    158 => array
        (
            "pts_m" => null ,
            "pts_mreg" => null,
            "pts_cg" => 0
        ),

    159 => array
        (
            "pts_m" => "",
            "pts_mreg" => 1,
            "pts_cg" => 1
        )

);

$count = 0;
foreach ($mm as $m) {
    foreach ($m as $value) {
        if($value !== false && $value !== "" && $value !== null) {
            $count++;
        }
    }
}
echo $count;
?>
share|improve this answer
Good idea - in that case array_filter could be used instead of the conditionals and $count++, no? – torr Jul 22 '11 at 20:40
add comment (requires an account with 50 reputation)

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.