Reputation: 1928
I have the following code, and I'd like to get away from the call-time pass-by-reference, (To convert from 5.2 to 5.3) but I'm not sure exactly sure what the correct way to do this would be (class, global variable, ?)
Here is a codepad that should have everything in it http://codepad.org/ombgFPMR
<?php
function count_things($item, $key, $total) {
$total++;
}
$counts = array(100 => 1,
101 => 1,
102 => array(
106 => 1,
107 => 1
),
103 => 1,
104 => 1,
105 => array(
108 => 1,
109 => array(
110 => 1,
111 => 1,
112 => 1
)
)
);
foreach($counts as $key => $count) {
$total = 0;
if(is_array($count)) {
$total++;
/* The below is a logic error. Array elements that contain arrays do not get
the callback function called on them. Therefore, any children with children
of their own will not be counted. In the output of this paste,
the final key, $final_counts[105]['total'], should have a value of 6, but it
actually has a value of 5. */
array_walk_recursive($count, 'count_things', &$total);
} else {
$total = $count;
}
$final_counts[$key]['total'] = $total;
}
print_r($final_counts);
?>
Output looks like:
Array
(
[100] => Array
(
[total] => 1
)
[101] => Array
(
[total] => 1
)
[102] => Array
(
[total] => 3
)
[103] => Array
(
[total] => 1
)
[104] => Array
(
[total] => 1
)
[105] => Array
(
[total] => 5
)
)
Upvotes: 4
Views: 1444
Reputation: 6012
You can use count
with COUNT_RECURSIVE
flag.
You should use closures for this, these were introduced in 5.3.0 so they should work.
<?php
$counts = array(
100 => 1,
101 => 1,
102 => array(
106 => 1,
107 => 1
),
103 => 1,
104 => 1,
105 => array(
108 => 1,
109 => array(
110 => 1,
111 => 1,
112 => 1
)
)
);
$final_counts = array();
foreach($counts as $key => $count) {
if(is_array($count)) {
$total = 1;
array_walk_recursive($count, function() use (&$total) {
$total++;
});
} else {
$total = $count;
}
$final_counts[$key]['total'] = $total;
}
print_r($final_counts);
I might be able to provide a better solution if you put your problem in context.
Upvotes: 3