21

Does anyone know how to count the occurrences of "photo" in this array:

    Array ( 
    [0] => stdClass Object ( [type] => photo [id] => 1404781893036 [created_time] => 2012-03-02T07:58:23+0000 ) 
    [1] => stdClass Object ( [type] => photo [id] => 14047818930362 [created_time] => 2012-03-01T14:58:53+0000 ) 
    [2] => stdClass Object ( [type] => status [id] => 1404781893036 [created_time] => 2012-03-01T09:49:40+0000 ) 
    [3] => stdClass Object ( [type] => status [id] => 14047818930362 [created_time] => 2012-03-01T09:36:04+0000 ) 
    [4] => stdClass Object ( [type] => photo [id] => 14047818930362 [created_time] => 2012-02-28T07:03:25+0000 ) 
    [5] => stdClass Object ( [type] => photo [id] => 1404781893036 [created_time] => 2012-02-27T09:15:34+0000 ) 
    [6] => stdClass Object ( [type] => photo [id] => 14047818930362 [created_time] => 2012-02-27T07:32:13+0000 ) 
    [7] => stdClass Object ( [type] => status [id] => 1404781893036 [created_time] => 2012-02-25T09:36:57+0000 )
    [8] => stdClass Object ( [type] => photo [id] => 1404781893036 [created_time] => 2012-02-23T08:46:43+0000 ) 
    [9] => stdClass Object ( [type] => status [id] => 1404781893036 [created_time] => 2012-02-22T21:04:30+0000 ) 
    [10] => stdClass Object ( [type] => status [id] => 1404781893036 [created_time] => 2012-02-21T20:38:27+0000 )
    [11] => stdClass Object ( [type] => photo [id] => 1404781893036 [created_time] => 2012-02-21T07:22:44+0000 ) 
    [12] => stdClass Object ( [type] => status [id] => 14047818930362 [created_time] => 2012-02-20T08:32:46+0000 ) 
    [13] => stdClass Object ( [type] => status [id] => 1404781893036 [created_time] => 2012-02-17T15:00:11+0000 ) )
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Georg
  • 610
  • 2
  • 8
  • 22

4 Answers4

57

To count matching occurance of a string in multidimensional array you will need to iterate over each array element and match the string and increment the count. Similiarly @Dor has suggested

$count = 0;
foreach ($array as $item) {
  if ($item->type === 'photo') {
    $count++;
  }
}

If you want achieve same in single dimensional array then It's pretty straightforward. You can use array_count_values PHP array function as explained below.

<?php
   $array = array(1, "test", 1, "php", "test");
   print_r(array_count_values($array));
?>

The above example will output:

Array
(
    [1] => 2
    [test] => 2
    [php] => 1
)
Roopendra
  • 7,674
  • 16
  • 65
  • 92
  • Iterate through the array and Increment a ctrPhoto whenever the type='photo' is encountered – Rahat Khanna Nov 20 '12 at 10:15
  • 2
    This should be the correct answer because it's simpler and avoid manual iteration – JDuarteDJ Jul 05 '13 at 12:09
  • 2
    This answer is not specific to the OP's question whereas Dor Shemer specifically catered his answer to the question hence why his is the accepted answer. Regardless, the answer to why I'm searching on SOF right now is this one so +1. – Jacksonkr Sep 30 '15 at 16:18
  • 1
    Your answer applies only on string and/or integer array, but not in objects array like in the OP question. – deltonio2 Jan 25 '17 at 08:57
  • This is the right answer to the wrong question. This answer does not work with the OP's multi-level data structure or resemble the data. It also does not isolate the requested value count -- it spews the count for all values in a 1-dimensional array. This technique also fails as a stand alone function call because if the sought value does not exist then the value will not be listed in the output array. This means additional handling is required to provide the default value of `0`. Though my downvote won't make a dent in this 56-upvoted answer, I feel I must downvote on principle. – mickmackusa Oct 24 '17 at 01:07
15
$count = 0;
foreach ($array as $item) {
  if ($item->type === 'photo') {
    $count++;
  }
}
hakre
  • 193,403
  • 52
  • 435
  • 836
dorsh
  • 23,750
  • 2
  • 27
  • 29
2

I'd like to acknowledge that the method by Dor Shemer is (IMO) the most direct, clean, readable, and reliable method. I just want to offer a few alternatives for those who prefer to use functional programming ...array_reduce() is a close second for me. Finally, I want to pinpoint a small gotcha for methods that use array_count_values() -- please read on...

Battery of Methods: (Demo)

$photo_count=0;  // establish default value
foreach($array as $objects){
    if($objects->type==='photo') ++$photo_count;  // pre-increment
}
echo "foreach result = $photo_count";

echo "array_reduce = ",array_reduce($array,function($carry,$objects){return $carry+($objects->type==='photo'?1:0);},0);

echo "array_filter & count = ",sizeof(array_filter($array,function($objects){return $objects->type==='photo';}));

echo "array_column & array_filter & count = ",sizeof(array_filter(array_column($array,'type'),function($v){return $v==='photo';}));

echo "array_map & array_count_values & array_replace = ",array_replace(['photo'=>0],array_count_values(array_map(function($o) {return $o->type;}, $array)))['photo'];

echo "array_map & array_count_values (gives Notice) = ",array_count_values(array_map(function($o) {return $o->type;}, $array))['photo'];

Input/Output using OP's sample data (no trouble):

$array=[
    (object)['type'=>'photo','id'=>1404781893036,'created_time'=>'2012-03-02T07:58:23+0000'],
    (object)['type'=>'photo','id'=>14047818930362,'created_time'=>'2012-03-01T14:58:53+0000'],
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-03-01T09:49:40+0000'],
    (object)['type'=>'status','id'=>14047818930362,'created_time'=>'2012-03-01T09:36:04+0000'],
    (object)['type'=>'photo','id'=>14047818930362,'created_time'=>'2012-02-28T07:03:25+0000'],
    (object)['type'=>'photo','id'=>1404781893036,'created_time'=>'2012-02-27T09:15:34+0000'],
    (object)['type'=>'photo','id'=>14047818930362,'created_time'=>'2012-02-27T07:32:13+0000'],
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-02-25T09:36:57+0000'],
    (object)['type'=>'photo','id'=>1404781893036,'created_time'=>'2012-02-23T08:46:43+0000'],
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-02-22T21:04:30+0000'],
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-02-21T20:38:27+0000'],
    (object)['type'=>'photo','id'=>1404781893036,'created_time'=>'2012-02-21T07:22:44+0000'],
    (object)['type'=>'status','id'=>14047818930362,'created_time'=>'2012-02-20T08:32:46+0000'],
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-02-17T15:00:11+0000']
];

// output:
foreach result = 7

array_reduce = 7

array_filter & count = 7

array_column & array_filter & count = 7

array_map & array_count_values & array_replace = 7

array_map & array_count_values = 7

Input/Output using data with no photo values (trouble with 2nd array_count_values() method):

$array=[
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-03-01T09:49:40+0000'],
    (object)['type'=>'status','id'=>14047818930362,'created_time'=>'2012-03-01T09:36:04+0000'],
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-02-25T09:36:57+0000'],
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-02-22T21:04:30+0000'],
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-02-21T20:38:27+0000'],
    (object)['type'=>'status','id'=>14047818930362,'created_time'=>'2012-02-20T08:32:46+0000'],
    (object)['type'=>'status','id'=>1404781893036,'created_time'=>'2012-02-17T15:00:11+0000']
];
// or if there are no object rows like: $array=[];
// output:
foreach result = 0

array_reduce = 0

array_filter & count = 0

array_column & array_filter & count = 0

array_map & array_count_values & array_replace = 0

array_map & array_count_values (gives Notice) = <br />
<b>Notice</b>:  Undefined index: photo in <b>[...][...]</b> on line <b>43</b><br />

array_count_values() doesn't bother to generate elements with a 0 count.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
1

Try with:

$input = array( /* your data */ );
$count = 0;
foreach ( $input as $value ) {
  if ( $value->type == 'photo' ) {
    $count++;
  }
}
hsz
  • 148,279
  • 62
  • 259
  • 315