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;
}
Related
I have an array:
$arr=array("A","B","C");
I want to make its all of combination as:
array("A")
array("B")
array("C")
array("A","B")
array("A","C")
array("B","C")
array("A","B","C")
i want to make an process all of this combinations but i don't want generate all combinations, store them in an array and apply function to them. Because this requires a lot of memory with large combinations. I have 40 items for this process (I have long time but i don't have enough memory).
I want to have a function like this:
function ProcessArrayCombinations($array){
foreach($array as $v){
//generate and process next combination of array
print_r($nextcombination);
}
}
Thank you.
This code recognizes the combinations as binary numbers, using the fact that there is a formula which states that the sum of all combinations possible from n elements is 2^n. Knowing its binary logarithm is integer, we can define a model where each possible binary number constructed from n digits is a set of combinations. Code is untested, if there are typos, please, let me know in comments.
function ProcessArrayCombinations($array) {
$status = array();
foreach ($array as $element) {
$status[] = false;
}
$elementCount = count($status);
$trues = 0;
while ($trues < $elementCount) {
$index = 0;
$stop = false;
while ((!$stop) && ($index < count($status)) && ($status[$index])) {
$status[$index] = false;
$trues--;
$index++;
}
$status[$index] = true;
$trues++;
//Found a new combination
//We should print elements from $array located at indexes fulfilling
//the criteria that the element having the same index in $status is true:
//for ($i = 0; $i < count($status); $i++) {
// if ($status[$i}) {
// print
// } else {
// don't print
// }
//}
}
}
I edited and used your function as below. Thank you again Lajos.
function ProcessArrayCombinations($array) {
$status = array();
foreach ($array as $element) {
$status[] = false;
}
$elementCount = count($status);
$trues = 0;
while ($trues < $elementCount) {
$index = 0;
$stop = false;
while ((!$stop) && ($index < count($status)) && ($status[$index])) {
$status[$index] = false;
$trues--;
$index++;
}
$status[$index] = true;
$trues++;
//Found a new combination
//We should print elements from $array located at indexes fulfilling
//the criteria that the element having the same index in $status is true:
for ($i = 0; $i < count($status); $i++) {
if ($status[$i]) {
echo $array[$i];
}
}
echo '<br/>';
}
}
I have an issue to deal with here (a logical error in my code 99%). I just can't seem to find the way to fix it, but I bet one of you will find the problem in no time!
I have to create a function which sorts array passed to it in asc or desc order, but can't use any array sorting functions !
I've been struggling with loops until now and I finally want to ask help from other devs ( you ).
Currently only code for ascending is worked on, descending will be no problem I assume once I do this one. It kinda of does sort values up to some point, but then stops ( it stops if the next smallest value is at the end of the passed array ). What could I do to prevent this and make it sort the whole array and it's elements?
Here is the code so far.
<?php
function order_array($array,$mode = 'ascending') {
$length = count($array);
if($mode == 'descending') {
return $array;
} else {
$sorted_array = array();
$used_indexes = array();
for($i = 0; $i < $length; $i++) {
$smallest = true;
echo $array[$i] . '<br/>';
for($y = 0; $y < $length; $y++) {
//echo $array[$i] . ' > ' . $array[$y] . '<br/>';
// if at ANY time during checking element vs other ones in his array, he is BIGGER than that element
// set smallest to false
if(!in_array($y,$used_indexes)) {
if($array[$i] > $array[$y]) {
$smallest = false;
break;
}
}
}
if($smallest) {
$sorted_array[] = $array[$i];
$used_indexes[] = $i;
}
}
return $sorted_array;
}
}
$array_to_sort = array(1, 3, 100, 99, 33, 20);
$sorted_array = order_array($array_to_sort);
print_r($sorted_array);
?>
I've solved the issue myself by doing it completely different. Now it sorts correctly all the elements of the passed in array. The logical issue I had was of using for() loop. The for() loop ran only a set ( length of passed array ) number of times, while we need it to loop more than that, because we will need to loop all the way untill we have a new sorted array in ascending order. Here is the code that will work
function order_array($array,$mode = 'ascending') {
if($mode == 'descending') {
// for() wont work here, since it will only loop an array length of times, when we would need it
// to loop more than that.
while(count($array)){
$value = MAX($array);
$key = array_search($value, $array);
if ($key !== false) {
unset($array[$key]);
}
$sorted[] = $value;
}
return $sorted;
} else {
// for() wont work here, since it will only loop an array length of times, when we would need it
// to loop more than that.
while(count($array)){
$value = MIN($array);
$key = array_search($value, $array);
if ($key !== false) {
unset($array[$key]);
}
$sorted[] = $value;
}
return $sorted;
}
}
function order_array($array,$mode = 'ascending') {
$length = count($array);
$sorted_array = array();
$used_indexes = array();
for($i = 0; $i < $length; $i++) {
$smallest = true;
echo $array[$i] . '<br/>';
for($y = 0; $y < $length; $y++) {
//echo $array[$i] . ' > ' . $array[$y] . '<br/>';
// if at ANY time during checking element vs other ones in his array, he is BIGGER than that element
// set smallest to false
if(!in_array($y,$used_indexes)) {
if($array[$i] > $array[$y]) {
$smallest = false;
break;
}
}
}
if($smallest) {
$sorted_array[] = $array[$i];
$used_indexes[] = $i;
}
if($mode == 'descending') {
return array_reverse($sorted_array);
}
return $sorted_array;
}
}
Let's say I have this array
$number = [2,1,4,3,6,2];
First pair the elements on an array by two's and find their difference
so this is the output in the first requirement
$diff[] = [1,1,4];
Second sum all the difference
this is the final output
$sum[] = [6];
Conditions:
the array size is always even
the first element in a pair is always greater than the second one, so their is no negative difference
What I've done so far is just counting the size of an array then after that I don't know how to pair them by two's. T_T
Is this possible in php? Is there a built in function to do it?
One line:
$number = [2,1,4,3,6,2];
$total = array_sum(array_map(function ($array) {
return current($array) - next($array);
}, array_chunk($number, 2)));
echo $total;
This should work fine:
<?
$number = array(2,1,4,3,6,2);
for($i=0;$i<count($number); $i+=2){
$dif[] = $number[$i] - $number[$i+1];
}
print_r($dif);
$sum = 0;
foreach ($dif as $item){
$sum += $item;
}
echo 'SUM = '.$sum;
?>
Working CODE
If you want all the different stages kept,
$numbers = [2,1,4,3,6,2];
$diff = [];
for($i=0,$c=count($numbers);$i<$c;$i+=2)
{
$diff[] = $numbers[$i]-$numbers[$i+1];
}
$sum = array_sum($diff);
Else, to just get the total and bypass the diff array:
$numbers = [2,1,4,3,6,2];
$total = 0;
for($i=0,$c=count($numbers);$i<$c;$i+=2)
{
$total += $numbers[$i]-$numbers[$i+1];
}
I have got this far it gives the required solution.
$arr = array(2,1,4,3,6,2);
$temp = 0;
$diff = array();
foreach ($arr as $key => $value) {
if($key % 2 == 0) {
$temp = $value;
}
else {
$diff[] = $temp - $value;
}
}
print_R($diff);
print 'Total :' . array_sum($diff);
Note : Please update if any one knows any pre-defined function than can sorten this code.
Please check and see if this works for you.
<?php
$sum=0;
$number = array(2,1,4,3,6,2);
for ($i=0;$i<=count($number);$i++) {
if ($i%2 == 1 ) {
$sum = $sum + $number[$i-1] - $number[$i];
}
}
print $sum;
?>
Well with your conditions in mind I came to the following
$number = [2,1,4,3,6,2];
$total = 0;
for($i = 0; $i < count($number); $i+=2) {
$total += $number[$i] - $number[$i + 1];
}
Try this one:
$number = array(2,1,4,3,6,2);
$diff = array();
$v3 = 0;
$i=1;
foreach($number as $val){
if ($i % 2 !== 0) {
$v1 = $val;
}
if ($i % 2 === 0) {
$v2 = $val;
$diff[] = $v1-$v2;
$v3+= $v1-$v2;
}
$i++;
}
print $v3;//total value
print_r($diff); //diff value array
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;
}
I need to transform my nested sets structure (mysql) into json for this spacetree
1) http://blog.thejit.org/wp-content/jit-1.0a/examples/spacetree.html
I found this function to create an array from nested sets:
2) http://semlabs.co.uk/journal/converting-nested-set-model-data-in-to-multi-dimensional-arrays-in-php
I can also convert php array into json with PHP function json_encode
My problem: the function nestify (from second link) gives me not exactly that i need. I need something like this: http://pastebin.com/m68752352
Can you help me change the function "nestify" so it gives me the correct array?
Here is this function one more time:
function nestify( $arrs, $depth_key = 'depth' )
{
$nested = array();
$depths = array();
foreach( $arrs as $key => $arr ) {
if( $arr[$depth_key] == 0 ) {
$nested[$key] = $arr;
$depths[$arr[$depth_key] + 1] = $key;
}
else {
$parent =& $nested;
for( $i = 1; $i <= ( $arr[$depth_key] ); $i++ ) {
$parent =& $parent[$depths[$i]];
}
$parent[$key] = $arr;
$depths[$arr[$depth_key] + 1] = $key;
}
}
return $nested;
}
The following snippet should do the trick, adapted from some PHP Doctrine code I found on the web :
function toHierarchy($collection)
{
// Trees mapped
$trees = array();
$l = 0;
if (count($collection) > 0) {
// Node Stack. Used to help building the hierarchy
$stack = array();
foreach ($collection as $node) {
$item = $node;
$item['children'] = array();
// Number of stack items
$l = count($stack);
// Check if we're dealing with different levels
while($l > 0 && $stack[$l - 1]['depth'] >= $item['depth']) {
array_pop($stack);
$l--;
}
// Stack is empty (we are inspecting the root)
if ($l == 0) {
// Assigning the root node
$i = count($trees);
$trees[$i] = $item;
$stack[] = & $trees[$i];
} else {
// Add node to parent
$i = count($stack[$l - 1]['children']);
$stack[$l - 1]['children'][$i] = $item;
$stack[] = & $stack[$l - 1]['children'][$i];
}
}
}
return $trees;
}