Hi anybody can help me to find the maximum value of the array that are given in the below . i expect the result of 650 is the maximum value....
$my_array = array(array(128,300,140)10,15,array(130,array(500,650)));
Here you go, using RecursiveArrayIterator in 3 readable lines of code:
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$flattenedArray = iterator_to_array($it);
$max = max($flattenedArray);
Or, if you want to not flatten (and copy), but prefer to iterate (uses far less memory, but slower):
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$max = 0;
foreach ($it as $value) {
$max = max($value, $max);
}
Flatten the array, then call max() on it. The return value of max() should be 650 from your example.
Also possible is
$data = array(array(128,300,140),10,15,array(130,array(500,650)));
$max = 0;
array_walk_recursive(
$data,
function($val) use (&$max) {
if($val > $max) $max = $val;
}
);
echo $max; // 650
You could also do it recursively, if the item is an array, call the function again to return the max item from that array.
In the end you should have always the max item and then in the last iteration, you could call the max from those results.
This does the trick:
function flatten($ar) {
$toflat = array($ar);
$res = array();
while (($r = array_shift($toflat)) !== NULL) {
foreach ($r as $v) {
if (is_array($v)) {
$toflat[] = $v;
} else {
$res[] = $v;
}
}
}
return $res;
}
$arr = array(array(128,300,140),10,15,array(130,array(500,650)));
echo max(array_flatten($arr));
EDIT: Updated flatten array with the one at How to "flatten" a multi-dimensional array to simple one in PHP?
<?php
$my_array = array(array(128,300,140),10,15,array(130,array(500,650)));
function findLargest($arr) {
$largest = 0;
foreach ($arr as $item) {
if (is_array($item)) {
$item = findLargest($item);
}
if ($item > $largest) {
$largest = $item;
}
}
return $largest;
}
echo "Largest is ".findLargest($my_array)."\n";
?>
function maximum($in)
{
if (!is_array($in)) $max = $in;
else foreach ($in as $element)
{
$elementMax = maximum($element);
if (isset($max)) $max = max($elementMax, $max); else $max = $elementMax;
}
return $max;
}
Related
I need to find the min and max position into an array where some value exist!
use a loop inside a loop to compare values is not an option ( my array has 100.000 values )
e.g=
$myarray[0]="red";
$myarray[1]="red";
$myarray[2]="blue";
$myarray[3]="blue";
$myarray[4]="blue";
$myarray[5]="red";
how to get the min and max position where blue exist?
Use the second argument for array_keys:
if($blue = array_keys($myarray, 'blue')) {
$min = min($blue);
$max = max($blue);
}
may be this is the answer?
function getMinKey($arr, $search){
if(!in_array($search, $arr)){
return false;
}
foreach($arr as $key => $value){
if($value == $search){
return $key;
}
}
}
function getMaxKey($arr, $search){
if(!in_array($search, $arr)){
return false;
}
$arrCount = count($arr)-1;
for($i = $arrCount; $i >=0; $i--){
if($arr[$i] == $search){
return $i;
}
}
}
All solutions, so far, have searched the whole array, which might be quite inefficient. You only need to search from the start upto the first "blue" and from the end downto the last "blue". Like this:
$find = "blue";
$first = false;
$last = false;
$max = count($myarray);
$key = 0;
while ($key < $max) {
if ($myarray[$key] == $find) {
$first = $key;
break;
}
$key++;
}
if ($first !== false) {
$key = --$max;
while ($key > 0) {
if ($myarray[$key] == $find) {
$last = $key;
break;
}
$key--;
}
}
Note that this code takes into account that nothing will be found. In that case $first and $last will contain false. It also checks to see if the $first was found to prevent searching through the array twice when there's clearly no need for that.
You can use array_keys with the search_value to extract all the matching keys, and then max and min to get the two ones that you want.
$keys = array_keys($myarray,'blue'); //[2,3,4]
$maxKey = max($keys); //4
$minKey = min($keys); //2
I have to advise that performance wise is better to do a for loop:
$length = count($myarray);
$minKey = FALSE;
$maxKey = FALSE;
$search = 'blue';
for($i=0;$i<$length;$i++){
if($myarray[$i] == $search){
if($minKey === FALSE) $minKey = $i;
$maxKey = $i;
}
}
I want to combine two arrays into a dictionary.
The keys will be the distinct values of the first array, the values will be all values from the second array, at matching index positions of the key.
<?php
$a=[2,3,4,5,6,7,8,9,10];
$b=[1,1,3,2,1,2,6,8,8];
?>
array_combine($b,$a);
Expected result as
<?php
/*
Value '1' occurs at index 0, 1 and 4 in $b
Those indices map to values 2, 3 and 6 in $a
*/
$result=[1=>[2,3,6],3=>4,2=>[5,7],6=>8,8=>[9,10]];
?>
There are quite a few PHP array functions. I'm not aware of one that solves your specific problem. you might be able to use some combination of built in php array functions but it might take you a while to weed through your choices and put them together in the correct way. I would just write my own function.
Something like this:
function myCustomArrayFormatter($array1, $array2) {
$result = array();
$num_occurrences = array_count_values($array1);
foreach ($array1 AS $key => $var) {
if ($num_occurrences[$var] > 1) {
$result[$var][] = $array2[$key];
} else {
$result[$var] = $array2[$key];
}
}
return $result;
}
hope that helps.
$a=[2,3,4,5,6,7,8,9,10];
$b=[1,1,3,2,1,2,6,8,8];
$results = array();
for ($x = 0; $x < count($b); $x++) {
$index = $b[$x];
if(array_key_exists ($index, $results)){
$temp = $results[$index];
}else{
$temp = array();
}
$temp[] = $a[$x];
$results[$index] = $temp;
}
print_r($results);
Here's one way to do this:
$res = [];
foreach ($b as $b_index => $b_val) {
if (!empty($res[$b_val])) {
if (is_array($res[$b_val])) {
$res[$b_val][] = $a[$b_index];
} else {
$res[$b_val] = [$res[$b_val], $a[$b_index]];
}
} else {
$res[$b_val] = $a[$b_index];
}
}
var_dump($res);
UPDATE: another way to do this:
$val_to_index = array_combine($a, $b);
$result = [];
foreach ($val_to_index as $value => $index) {
if(empty($result[$index])){
$result[$index] = $value;
} else if(is_array($result[$index])){
$result[$index][] = $value;
} else {
$result[$index] = [$result[$index], $value];
}
}
var_dump($result);
I basically want to change the value of a multidimensional array by adding to the previous value.
Example:
$arr=array(1,2,3);
foreach($arr as $val){
$arrTotal[1][2][3]=$val;
}
This would make $arrTotal[1][2][3]=3
What I really want is $arrTotal[1][2][3]=6
3+2+1.
I have tried an approach like so:
$arrTotal[1][2][3]+=$val;
But to no avail.
Easiest approach:
$arr = array(1,2,3);
$arrTotal[1][2][3] = array_sum($arr);
More general solution:
<?php
function hierarchical_array_sum(array $arr) {
$parent = null;
$current = $total = new ArrayObject;
foreach ($arr as $val) {
$parent = $current;
$current = $current[$val] = new ArrayObject;
}
if ($parent !== null) {
$parent[$val] = array_sum($arr);
}
$total = json_decode(json_encode($total), true);
}
var_dump(hierarchical_array_sum(array(1, 2, 3, 4, 5, 6, 7)));
$arrTotal[1][2][3] = 0;
foreach($arr as $val){
$arrTotal[1][2][3] = $arrTotal[1][2][3] + $val;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a way to find how how “deep” a PHP array is?
I am trying to write a method to count the number of dimensions of an array. The following gives me a correct count of dimensions
$array = array();
$array[0] = array();
$array[0][0] = 0;
$array[0][1] = array();
$array[0][1][0] = 10;
$array[0][1][1] = 11;
echo '<p>'.\utility\arrayTools\arrayTools::numberOfDimensions($array).'</p>';
//3 Dimensons
The second examples also gives me a correct count of the number of dimensions
$array = array();
$array[0] = array();
$array[0][0] = 0;
$array[0][1] = array();
$array[0][1][0] = 10;
$array[0][1][1] = 11;
$array[1] = 1;
$array[2] = 2;
//3 Dimensions
But the following example gives me too high of a count
$array = array();
$array[0] = array();
$array[0][0] = 0;
$array[0][1] = array();
$array[0][1][0] = 10;
$array[0][1][1] = 11;
$array[1] = 1;
$array[2] = 2;
$array[3] = array();
$array[3][0] = 30;
//Should still be 3 dimensions, but gives me 4
The method I am using is below
//Method
public static function numberOfDimensions($array)
{
if(func_num_args() === 2){
if(is_int(func_get_arg(1))){
$number_of_dimensions = func_get_arg(1);
}else{
throw new Exception('The second argumment must be an interger');
}
}else{
$number_of_dimensions = 0;
}
if(is_array($array) === TRUE){
$number_of_dimensions++;
if(self::isMultiDimensional($array) === TRUE){
foreach($array as $iteration){
$number_of_dimensions = self::numberOfDimensions($iteration,$number_of_dimensions);
}
return $number_of_dimensions;
}else{
return $number_of_dimensions;
}
}else{
return $number_of_dimensions;
}
}
I already know the problem is it is still adding for every multidimensional even though the count may be equal to or less then the number of dimensions. But what I can't figure out is how to get it to find the highest number of dimensions and stop counting
Here is a simpler version of your script
function numberOfDimensions($array) {
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$d = 0;
foreach ( $it as $v )
$it->getDepth() >= $d and $d = $it->getDepth();
return ++ $d;
}
From another answer here on SO:
function array_depth($array) {
$max_depth = 1;
foreach ($array as $value) {
if (is_array($value)) {
$depth = array_depth($value) + 1;
if ($depth > $max_depth) {
$max_depth = $depth;
}
}
}
return $max_depth;
}
I havn't written any PHP in a very long while, so there may very well be mistakes in my code, excuse me in advance.
function numberOfDimensions($array,$so_far=0){
if !is_array($array){
return 0;
}
$max_dims = 0;
foreach($array as $element){
$element_dims = numberOfDimensions($array);
$max_dims = max($max_dims,$element_dims);
}
return $max_dims +1;
}
This function assumes it is being called with an array as parameter, thus the minimum depths is 1.
It then recursively looks at all child elements, and if the child is deeper than already known, it add the depth of the child to the calculated depth:
function numberOfDimensions($subject) {
// scalar value has depth 0
if(!is_array($subject)) return 0;
// array has min depth of 1
$depth = 1;
foreach ($subject as $element) {
if (is_array($element)) {
// is the sub array deeper than already known?
$sub_depth = numberOfDimensions($element);
if ($sub_depth >= $depth) {
$depth += $sub_depth;
}
}
}
return $depth;
}
Eg:
$array= array(array(141,151,161),2,3,array(101,202,array(303,606)));
output :606
What you need is to recursively go through your array ; which means the max function, which is not recursive, will not be "enough".
But, if you take a look at the users's notes on the manual page of max, you'll find this note from tim, who proposes this recursive function (quoting) :
function multimax( $array ) {
// use foreach to iterate over our input array.
foreach( $array as $value ) {
// check if $value is an array...
if( is_array($value) ) {
// ... $value is an array so recursively pass it into multimax() to
// determine it's highest value.
$subvalue = multimax($value);
// if the returned $subvalue is greater than our current highest value,
// set it as our $return value.
if( $subvalue > $return ) {
$return = $subvalue;
}
} elseif($value > $return) {
// ... $value is not an array so set the return variable if it's greater
// than our highest value so far.
$return = $value;
}
}
// return (what should be) the highest value from any dimension.
return $return;
}
Using it on your array :
$arr= array(array(141,151,161),2,3,array(101,202,array(303,404)));
$max = multimax($arr);
var_dump($max);
Gives :
int 404
Of course, this will require a bit more testing -- but it should at least be a start.
(Going through the users' notes on manual pages is always a good idea : if you're having a problem, chances are someone else has already had that problem ;-) )
Same idea as Pascal's solution, only shorter thanks to the Standard PHP Library
$arr= array(array(141,151,161),2,3,array(101,202,array(303,404)));
echo rmax($arr);
function rmax(array $arr) {
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
// initialize $max
$it->next(); $max = $it->current();
// "iterate" over all values
foreach($it as $v) {
if ( $v > $max ) {
$max = $v;
}
}
return $max;
}
http://www.java2s.com/Code/Php/Data-Structure/FindtheMaximumValueinaMultidimensionalArray.htm
function recursive_array_max($a) {
foreach ($a as $value) {
if (is_array($value)) {
$value = recursive_array_max($value);
}
if (!(isset($max))) {
$max = $value;
} else {
$max = $value > $max ? $value : $max;
}
}
return $max;
}
$dimensional = array(
7,
array(3, 5),
array(5, 4, 7, array(3, 4, 6), 6),
14,
2,
array(5, 4, 3)
);
$max = recursive_array_max($dimensional);
$arr = array(array(141,151,161), 2, 3, array(101, 202, array(303,404)));
$callback = function ($value, $key) use (&$maximo) {
if( $value > $maximo){
$maximo = $value;
}
};
array_walk_recursive($arr, $callback);
echo '<pre>'; print_r($maximo);``
A more elegant solution:
function MaxArray($arr)
{
function findMax($currentValue, $currentKey)
{
global $maxValue;
$maxValue = ($currentValue > $maxValue ? $currentValue : $maxValue);
}
array_walk_recursive($arr, 'findMax');
return $GLOBALS['maxValue'];
}
It's very simple
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
$max = max(iterator_to_array($iterator, false));
Finding the max avoiding too much recursion :
function array_max(array $array) {
$context = func_get_args();
$max = -INF;
while (!empty($context)) {
$array = array_pop($context);
while (!empty($array)) {
$value = array_pop($array);
if (is_array($value)) {
array_push($context, $value);
}
elseif ($max < $value) {
$max = $value;
}
}
}
return $max;
}
A more general method avoiding too much recursion :
function array_reduce_recursive($default, array $array, $callback = null) {
$context = func_get_args();
$count = func_num_args();
if (is_callable(func_get_arg($count - 1))) {
$callback = array_pop($context);
}
else {
$callback = create_function('$x, $y', 'return $x < $y ? $y : $x;');
}
$reduced = array_shift($context);
while (!empty($context)) {
$array = array_pop($context);
while (!empty($array)) {
$value = array_pop($array);
if (is_array($value)) {
array_push($context, $value);
}
else {
$reduced = $callback($reduced, $value);
}
}
}
return $reduced;
}
function array_max_recursive() {
$args = func_get_args();
$callback = create_function('$x, $y', 'return $x < $y ? $y : $x;');
return array_reduce_recursive(-INF, $args, $callback);
}
By this way you can specify the callback method if you are looking for something else than the biggest number. Also this method takes several arrays.
The end way is less efficient of course.
With this you have a full compatibility with lot of PHP version.
function MaxArray($arr) {
$maximum = 0;
foreach ($arr as $value) {
if (is_array($value)) {
//print_r($value);
$tmaximum = MaxArray($value);
if($tmaximum > $maximum){
$maximum = $tmaximum;
}
}
else
{
//echo $value.'\n';
if($value > $maximum){
$maximum = $value;
}
}
}
return $maximum;
}