12

I'm trying to write a function which counts array elements recursively.

But result is false.

What could it be problem?

$schema = array(
    'div' => array(
        'class' => 'lines',
        'div' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Soap'
        ),
        'layer' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Ball'
            )
        )
);

function count_r($array, $i = 0){
    foreach($array as $k){
        if(is_array($k)){ $i += count_r($k, count($k)); }
        else{ $i++; }
    }
    return $i;
}

echo count_r($schema);
4
  • False or zero? Run var_dump($schema) and tell us the output. Commented Aug 25, 2013 at 14:24
  • @ConnorPeet It returns 14, this is false result Commented Aug 25, 2013 at 14:24
  • Ah, that is quite different. Why do you have count_r($k, count($k));? Shouldn't need the second argument. Commented Aug 25, 2013 at 14:26
  • But without this argument how Can I count recursively? Commented Aug 25, 2013 at 14:28

7 Answers 7

46

There is a built-in function in PHP that you can use: count().

This is how you can use it:

count($schema, COUNT_RECURSIVE);

This function also detects recursion to avoid infinite loops so it's safer than solutions in other answers.

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

1 Comment

This should be the proper solution, since as @Christian P says, PHP has a built in method to accomplish this. And it's simply using the 'count' function. count($multi_level_array, COUNT_RECURSIVE)
14

PHP has a built-in method for this purpose, called count(). If passed without any additional parameters, count() returns the number of array keys on the first level. But, if you pass a second parameter to the count method count( $schema, true ), then the result will be the total number of keys in the multi-dimensional array. The response marked as correct only iterates first and second level arrays, if you have a third child in that array, it will not return the correct answer.

This could be written as a recursive function, if you really want to write your own count() method, though.

Comments

1

your function could be simple as

function count_r($array, $i = 0){
    foreach($array as $k){
        $i++;
        if(is_array($k)){ 
            $i += count_r($k); 
        }
    }
    return $i;
}

Comments

1

If you want to count specific keys/values you can use the built-in array_walk_recursive with a closure function.

$schema = array(
    'div' => array(
        'class' => 'lines',
        'div' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Soap'
        ),
        'layer' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Ball'
            )
        )
);

$elements = 0;
array_walk_recursive($schema, function($value, $key) use (&$elements) {
  if (strstr($value, 'Product')) $elements++;
});

print $elements; // 2

/*
Values
  lines
  Product Name
  Soap
  Product Name
  Ball

Keys
  class
  key
  val
  key
  val
*/

1 Comment

This is the correct answer to a different question.
1

Transferred from comment below answer:

Basically, as you're adding the count_r of that array to the current level, you don't need to factor in the count in the second argument - you'd basically be adding it twice. You need the "1" in there, however, to count the array itself. If you'd want to count just the elements and not the arrays, you would just make the "1" a "0".

$schema = array(
    'div' => array(
        'class' => 'lines',
        'div' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Soap'
        ),
        'layer' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Ball'
            )
        )
);

function count_r($array, $i = 0){
    foreach($array as $k){
        if(is_array($k)){ $i += count_r($k, 1); }
        else{ $i++; }
    }
    return $i;
}

echo count_r($schema);

This is tested and works correctly.

Comments

0

I have altered you code.. Please check it. It is working fine.

$schema = array(
'div' => array(
    'class' => 'lines',
    'div' => array(
         'span' => array(
            'key' => 'Product Name'
        ),
        'val' => 'Soap'
    ),
    'layer' => array(
         'span' => array(
            'key' => 'Product Name'
        ),
        'val' => 'Ball'
        )
    )

);

function count_r($array){
 foreach($array as $k){
    if(is_array($k)){
            $i += count_r($k); 
        }
    else{
        $i++; 
    }
}
return $i;

} echo count_r($schema);

Comments

0

count($array, COUNT_RECURSIVE)-count($array)

2 Comments

Why have you dumped this unexplained code here? This is not a high quality answer. Why do you recommend it? What does it do? How does it work? Why is it better than all previous answers? Please edit your post.
If I understand correctly how count works, this is valid as far as you only have array of dimension equal 2 (and the values you want to count only in the deepest level - the second dimension). It will recursively count all keys and subtracts keys in first dimension making it count of keys in second dimension.

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.