tags:

views:

202

answers:

5

hi there,

I have an array structure that looks like this:

    Array
(
    [0] => Array
        (
            [type] => image
            [data] => Array
                (
                    [id] => 1
                    [alias] => test
                    [caption] => no caption
                    [width] => 200
                    [height] => 200
                )

        )

    [1] => Array
        (
            [type] => image
            [data] => Array
                (
                    [id] => 2
                    [alias] => test2
                    [caption] => hello there
                    [width] => 150
                    [height] => 150
                )

        )

)

My question is, how can I get a count of the number of embedded arrays that have their type set as image (or anything else for that matter)? In practise this value can vary.

So, the above array would give me an answer of 2.

Thanks

A: 

The simplest way would simply be to loop over all the child arrays and check their type, incrementing a counter if it matches the required type.

$count = 0;
foreach ( $myarray as $child ){
    if ( $child['type'] == 'image' ){
        $count++;
    }
}

If you have PHP 5.3.0 or better you could use array_reduce (untested):

$count = array_reduce($myarray, 
                      function($c, $a){ return $c + (int)($a['type'] == 'image'); },
                      0
         );

Both of these could be moved into a function returning $count which would allow you to specify the type to count. For example:

function countTypes(array $haystack, $type){
    $count = 0;
    foreach ( $haystack as $child ){
        if ( $child['type'] == $type ){
            $count++;
        }
    }
    return $count;
}

As you can see from other answers there is far more error checking you could do, however you as you haven't said what should be impossible (which you would want to use assert for).

The possible errors are:

  • The child is not an array
  • The child does have the type key set

If your array should always be set out like your example, failing silently (by putting a check in an if statement) would be a bad idea as it would mask an error in the program elsewhere.

Yacoby
Thanks - a lot of great answers from everyone!
Sergio
+1  A: 

You'll have to iterate over each element of your array and check whether element match your condition:

$data = array(...);

$count = 0;
foreach ($data as $item) {
    if ('image' === $item['type']) {
        $count++;
    }
}

var_dump($count);
Crozin
+1  A: 

Try this:

function countArray(array $arr, $arg, $filterValue)
{
    $count = 0;
    foreach ($arr as $elem)
    {
        if (is_array($elem) &&
                isset($elem[$arg]) &&
                $elem[$arg] == $filterValue)
            $count++;
    }
    return $count;
}

For your example, you would call it like this:

$result = countArray($array, 'type', 'image');
Franz
If `$elem[$arg]` is not set then it will not equal `$filter` so that check is kind of redundant, eh? You also put `$filterValue` rather than `$filter`.
animuson
Thanks for the typo you found. Not sure about the other thing, though - I believe on some systems you'd get a warning...
Franz
+1  A: 
<?php
$arr    = // as above
$result = array();

for ( $i = 0; $i < count( $arr ); $i++ )
{
    if ( !isset( $result[ $arr[$i]['type'] ] ) )
        $result[ $arr[$i]['type'] ] = 0;
    $result[ $arr[$i]['type'] ]++;
}

echo $result['image']; // 2
?>
poke
+1  A: 

In addition to Yacoby's answer, you could do it functional-style with a closure if you're using PHP 5.3:

$count = 0;
array_walk($array, function($item)
{
    if ($item['type'] == 'image')
    {
        $count++;
    }
});
Will Vousden