|
array_reduce
Iteratively reduce the array to a single value using a callback function
(PHP 4 >= 4.0.5, PHP 5)
Example 273. array_reduce() example<?php Code Examples / Notes » array_reducehayley 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 > 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 Languagearray_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 |