Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Array Functions : array_reduce

array_reduce

Iteratively reduce the array to a single value using a callback function (PHP 4 >= 4.0.5, PHP 5)
mixed array_reduce ( array input, callback function [, int initial] )

Example 273. array_reduce() example

<?php
function rsum($v, $w)
{
   
$v += $w;
   return
$v;
}

function
rmul($v, $w)
{
   
$v *= $w;
   return
$v;
}

$a = array(1, 2, 3, 4, 5);
$x = array();
$b = array_reduce($a, "rsum");
$c = array_reduce($a, "rmul", 10);
$d = array_reduce($x, "rsum", 1);
?>

Code Examples / Notes » array_reduce

hayley watson

To make it clearer about what the two parameters of the callback are for, and what "reduce to a single value" actually means (using associative and commutative operators as examples may obscure this).
The first parameter to the callback is an accumulator where the result-in-progress is effectively assembled. If you supply an $initial value the accumulator starts out with that value, otherwise it starts out null.
The second parameter is where each value of the array is passed during each step of the reduction.
The return value of the callback becomes the new value of the accumulator. When the array is exhausted, array_reduce() returns accumulated value.
If you carried out the reduction by hand, you'd get something like the following lines, every one of which therefore producing the same result:
<?php
array_reduce(array(1,2,3,4), 'f',         99             );
array_reduce(array(2,3,4),   'f',       f(99,1)          );
array_reduce(array(3,4),     'f',     f(f(99,1),2)       );
array_reduce(array(4),       'f',   f(f(f(99,1),2),3)    );
array_reduce(array(),        'f', f(f(f(f(99,1),2),3),4) );
f(f(f(f(99,1),2),3),4)
?>
If you made function f($v,$w){return "f($v,$w)";} the last line would be the literal result.
A PHP implementation might therefore look something like this (less details like error checking and so on):
<?php
function array_reduce($array, $callback, $initial=null)
{
$acc = $initial;
foreach($array as $a)
$acc = $callback($acc, $a);
return $acc;
}
?>


yuki dot kodama

This code will reduce array deeply.
<?php
function print_s($s) {
return is_null($s) ? "NULL" : (is_array($s) ? "Array" : ($s ? "TRUE" : "FALSE"));
}
function r_and_dp($a, $b) {
echo "phase1:" . print_s($a) . "," . print_s($b) . "
\n";
if(is_array($a)) {
$a = array_reduce($a, "r_and_dp");
}
if(is_array($b)) {
$b = array_reduce($b, "r_and_dp");
}
echo "phase2:" . print_s($a) . "," . print_s($b) . "
\n";
$a = is_null($a) ? TRUE : $a;
$b = is_null($b) ? TRUE : $b;
echo "phase3:" . print_s($a) . "," . print_s($b) . "
\n";
return $a && $b;
}
$bools = array(TRUE, array(FALSE, TRUE), TRUE);
echo print_s(array_reduce($bools, "r_and_dp")) . "
\n";
// result: FALSE
?>
When using boolean, you have to carefully set an "initial" argument.
<?php
function r_or_dp($a, $b) {
if(is_array($a)) {
$a = array_reduce($a, "r_or_dp");
}
if(is_array($b)) {
$b = array_reduce($b, "r_or_dp");
}
return (is_null($a) ? FALSE : $a) || (is_null($b) ? FALSE : $b);
}
?>


php dot net

There is an error/misleading item in the documentation
[, int initial]
int is not constrained to an integer, it can be any data type (although I've not tested ALL data types)
and $v is the cumulative part, the current value of the reduction.
and I'll take the liberty to add another example, as used in my code
<?php
function reduceToTable($html, $p) {
   $html .= "<TR><TD><a href=\"$p.html\">$p</a></td>\n";
   return $html;
}
$list = Array("page1", "page2", "page3");
$tab = array_reduce($list, "reduceToTable", "<table>\n");
echo $tab . "</table>\n";
?>
hmm, getting stuff on one line sure is tricky, it get's wordwrapped on the char count in html so &gt; counts as 4 chars not one so by the time you've counted "< you've used up 8 chars
If it get's through moderation could someone please make it look ok :)


david dot tulloh

The code supplied by cuntbubble is unfortunately incorrect.
Running it I got the output:
0<TR><TD><a href="page1.html">page1</a></td>
<TR><TD><a href="page2.html">page2</a></td>
<TR><TD><a href="page3.html">page3</a></td>
</table>
So php, not finding an integer, used int(0) to start the process.  I've tested to confirm this.


seanj.jcink.com

The code posted below by bishop to count the characters of an array is simply... erm... well useless to me...
$array=Array("abc","de","f");
strlen(implode("",$array)); //6
works; and is much smaller. Probably much faster too.


bdechka

The above code works better this way.
<?php
function reduceToTable($html, $p) {
  $html .= "<TR><TD><a href=\"$p.html\">$p</a></td></tr>\n";
  return $html;
}
$list = Array("page1", "page2", "page3");
$tab = array_reduce($list, "reduceToTable");
echo "<table>".$tab . "</table>\n";
?>


tonicpeddler

in response to php dot net at cuntbubble dot com
actually when you pass a value to a function that accepts a specific data type, php automatically evaluates that value as the data type expected


ildar dash sh

in rare cases when an array is a set of numeric values and result is one of sum or product of numbers the next examples may be useful
<?php
// sum of array items
echo eval('return ' . implode('+', $nums) . ';');
// product of array items
echo eval('return ' . implode('*', $nums) . ';');
?>
the reason of these codes is omitting of single used per script of callbacks


janez r.

In PHP ver. 4.3.1 the initial value parameter allowed for string type also. In PHP ver. 5.1.6 this param is now converted to int and callback function will receive number 0 when initial param his an empty string.
<?php
function arc ($reduced, $item)
{
 $reduced = $item.$reduced;
 return $reduced;
}
arc( array(a,b,c), "arc", "" );
?>
Output in PHP 4.3.1: cba
Output in PHP 5.1.6: cba0
Possible solution:
<?php
function arc ($reduced, $item)
{
 if ($reduced === 0)  $reduced = "";
 $reduced = $item.$reduced;
 return $reduced;
}
?>


marcel dot oehler

I've just experienced some really strange behaviour of array_reduce in PHP 5.0.4:
$result = array( 0, 17, 0, 0, 33, 0, 0, 0, 0, 50);
$total = array_reduce( $result, "sumCalc", 0);
function sumCalc( $a, $b){
return $a + $b;
}
and $total equals to 83!
I know, this could be done easier, but it should work nevertheless. Has anybody experienced something similar? I will avoid using array_reduce in the future...


bishop

Count the total number of characters in an array of strings:
<?php
$lines = array ('abc', 'd', 'ef');
$totalChars = array_reduce($lines, create_function('$v,$w','return $v + strlen($w);'), 0);
// $totalChars === 6
?>


janez r.

--REPOST, fixed some typos, please replace previous note--
In PHP ver. 4.3.1 the initial value parameter allowed for string type also. In PHP ver. 5.1.6 this param is now converted to int and callback function will receive number 0 when initial param is an empty string.
<?php
function arc ($reduced, $item)
{
 $reduced = $item.$reduced;
 return $reduced;
}
array_reduce( array(a,b,c), "arc", "" );
?>
Output in PHP 4.3.1: cba
Output in PHP 5.1.6: cba0
Possible solution:
<?php
function arc ($reduced, $item)
{
 if ($reduced === 0)  $reduced = "";
 $reduced = $item.$reduced;
 return $reduced;
}
?>


Change Language


Follow Navioo On Twitter
array_change_key_case
array_chunk
array_combine
array_count_values
array_diff_assoc
array_diff_key
array_diff_uassoc
array_diff_ukey
array_diff
array_fill_keys
array_fill
array_filter
array_flip
array_intersect_assoc
array_intersect_key
array_intersect_uassoc
array_intersect_ukey
array_intersect
array_key_exists
array_keys
array_map
array_merge_recursive
array_merge
array_multisort
array_pad
array_pop
array_product
array_push
array_rand
array_reduce
array_reverse
array_search
array_shift
array_slice
array_splice
array_sum
array_udiff_assoc
array_udiff_uassoc
array_udiff
array_uintersect_assoc
array_uintersect_uassoc
array_uintersect
array_unique
array_unshift
array_values
array_walk_recursive
array_walk
array
arsort
asort
compact
count
current
each
end
extract
in_array
key
krsort
ksort
list
natcasesort
natsort
next
pos
prev
range
reset
rsort
shuffle
sizeof
sort
uasort
uksort
usort
eXTReMe Tracker