From: Robert Cummings on 15 Mar 2010 22:14 Jim Lucas wrote: > Daevid Vincent wrote: >> Anyone have a function that will return an integer of the number of >> dimensions an array has? >> >> I did some quick searches and came up with nothing. >> The closest was here of someone asking the same thing, but his solution >> isn't right: >> http://www.bigresource.com/PHP-count-array-dimensions-VrIahx1b.html >> http://php.net/manual/en/function.count.php >> >> From a human standpoint, it's easy to see, "oh, this is a TWO >> dimensional"... >> > > How about this... Using a slightly modified array that you posted, I came up > with this in about 10 minutes > > <pre>I am working with the following data structure > > <?php > > $in = array( > 0 => array( > 0 => array('Flight Number', 'flight_number'), > 1 => array( > 0 => array('Timestamp Departure', 'timestamp_departure'), > 1 => array('Timestamp Arrival', 'timestamp_arrival'), > ) > ), > 1 => array('Departure City', 'departure_city'), > 2 => array('Arrival City', 'arrival_city'), > ); > > print_r($in); > > echo "\n\n"; > > $max_depth = 0; > $cur_depth = 0; > function max_array_depth($ar) { > global $cur_depth, $max_depth; > if ( is_array($ar) ) { > $cur_depth++; > if ( $cur_depth > $max_depth ) { > $max_depth = $cur_depth; > } > foreach ( $ar AS $row ) { > max_array_depth($row); > } > $cur_depth--; > } > } > > max_array_depth($in); > > echo "Max depth of array is: {$max_depth}"; > > ?></pre> > > http://www.cmsws.com/examples/php/testscripts/daevid(a)daevid.com/0002.php Globals are dirty for this kind of recursive utility function. Here's a cleaner example: <?php function get_array_depth( $array ) { if( !is_array( $array ) ) { return 0; } $maxDepth = 0; foreach( $array as $value ) { if( ($subDepth = get_array_depth( $value )) > $maxDepth ) { $maxDepth = $subDepth; } } return 1 + $maxDepth; } ?> Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP
From: Richard Quadling on 16 Mar 2010 09:07 On 15 March 2010 23:45, Daevid Vincent <daevid(a)daevid.com> wrote: > Anyone have a function that will return an integer of the number of > dimensions an array has? /** * Get the maximum depth of an array * * @param array &$Data A reference to the data array * @return int The maximum number of levels in the array. */ function arrayGetDepth(array &$Data) { static $CurrentDepth = 1; static $MaxDepth = 1; array_walk($Data, function($Value, $Key) use(&$CurrentDepth, &$MaxDepth) { if (is_array($Value)) { $MaxDepth = max($MaxDepth, ++$CurrentDepth); arrayGetDepth($Value); --$CurrentDepth; } }); return $MaxDepth; } Extending Jim and Roberts comments to this. No globals. By using a reference to the array, large arrays are not copied (memory footprint is smaller). And by using array_walk, a separate internal pointer is used, so no need to worry about losing your position on the array. Something to watch out for though is recursion in the array. If a value in the array is a reference to another part of the array, you are going to loop around for ever. $Data = array(&$Data); for example, with the line ... echo "$CurrentDepth, $MaxDepth, $Key\n"; in the callback function() will report 17701 before crashing out (no stack error surprisingly enough). Regards, Richard Quadling. -- ----- Richard Quadling "Standing on the shoulders of some very clever giants!" EE : http://www.experts-exchange.com/M_248814.html EE4Free : http://www.experts-exchange.com/becomeAnExpert.jsp Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731 ZOPA : http://uk.zopa.com/member/RQuadling
From: Robert Cummings on 16 Mar 2010 10:46 Richard Quadling wrote: > On 15 March 2010 23:45, Daevid Vincent <daevid(a)daevid.com> wrote: >> Anyone have a function that will return an integer of the number of >> dimensions an array has? > > /** > * Get the maximum depth of an array > * > * @param array &$Data A reference to the data array > * @return int The maximum number of levels in the array. > */ > function arrayGetDepth(array &$Data) { > static $CurrentDepth = 1; > static $MaxDepth = 1; > > array_walk($Data, function($Value, $Key) use(&$CurrentDepth, &$MaxDepth) { > if (is_array($Value)) { > $MaxDepth = max($MaxDepth, ++$CurrentDepth); > arrayGetDepth($Value); > --$CurrentDepth; > } > }); > > return $MaxDepth; > } > > Extending Jim and Roberts comments to this. No globals. By using a > reference to the array, large arrays are not copied (memory footprint > is smaller). Using a reference actually increases overhead. References in PHP were mostly useful in PHP4 when assigning objects would cause the object to be copied. But even then, for arrays, a Copy on Write (COW) strategy was used (and is still used) such that you don't copy any values. Try it for yourself: <?php $copies = array(); $string = str_repeat( '*', 1000000 ); echo memory_get_usage()."\n"; for( $i = 0; $i < 1000; $i++ ) { $copies[] = $string; } echo memory_get_usage()."\n"; ?> Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP
From: Peter Lind on 16 Mar 2010 10:57 This is one example where references actually decrease memory usage. The main reason is the recursive nature of the function. Try <?php echo memory_get_usage() . PHP_EOL; $array = range(0,1000000); $array[10] = range(0,10); $array[20] = range(0,10); $array[30] = range(0,10); $array[40] = range(0,10); $array[50] = range(0,10); $array[60] = range(0,10); $array[70] = range(0,10); $array[80] = range(0,10); $array[90] = range(0,10); $array[100] = range(0,10); echo memory_get_usage() . PHP_EOL; carray($array); function carray ($array) { foreach ($array as $value) { if (is_array($value)) carray($value); } echo memory_get_usage() . PHP_EOL; echo count($array) . PHP_EOL; } echo memory_get_usage() . PHP_EOL; And then compare with: <?php echo memory_get_usage() . PHP_EOL; $array = range(0,1000000); $array[10] = range(0,10); $array[20] = range(0,10); $array[30] = range(0,10); $array[40] = range(0,10); $array[50] = range(0,10); $array[60] = range(0,10); $array[70] = range(0,10); $array[80] = range(0,10); $array[90] = range(0,10); $array[100] = range(0,10); echo memory_get_usage() . PHP_EOL; carray($array); function carray (&$array) { $i = 0; foreach ($array as $value) { if (is_array($value)) carray($value); } echo memory_get_usage() . PHP_EOL; echo count($array) . PHP_EOL; } echo memory_get_usage() . PHP_EOL; The memory usage spikes in the first example when you hit the second array level - you don't see the same spike in the second example. Regards Peter On 16 March 2010 15:46, Robert Cummings <robert(a)interjinn.com> wrote: > > > Richard Quadling wrote: >> >> On 15 March 2010 23:45, Daevid Vincent <daevid(a)daevid.com> wrote: >>> >>> Anyone have a function that will return an integer of the number of >>> dimensions an array has? >> >> /** >> Â * Get the maximum depth of an array >> Â * >> Â * @param array &$Data A reference to the data array >> Â * @return int The maximum number of levels in the array. >> Â */ >> function arrayGetDepth(array &$Data) { >> Â Â Â Â static $CurrentDepth = 1; >> Â Â Â Â static $MaxDepth = 1; >> >> Â Â Â Â array_walk($Data, function($Value, $Key) use(&$CurrentDepth, >> &$MaxDepth) { >> Â Â Â Â Â Â Â Â if (is_array($Value)) { >> Â Â Â Â Â Â Â Â Â Â Â Â $MaxDepth = max($MaxDepth, ++$CurrentDepth); >> Â Â Â Â Â Â Â Â Â Â Â Â arrayGetDepth($Value); >> Â Â Â Â Â Â Â Â Â Â Â Â --$CurrentDepth; >> Â Â Â Â Â Â Â Â } >> Â Â Â Â }); >> >> Â Â Â Â return $MaxDepth; >> } >> >> Extending Jim and Roberts comments to this. No globals. By using a >> reference to the array, large arrays are not copied (memory footprint >> is smaller). > > Using a reference actually increases overhead. References in PHP were mostly > useful in PHP4 when assigning objects would cause the object to be copied.. > But even then, for arrays, a Copy on Write (COW) strategy was used (and is > still used) such that you don't copy any values. Try it for yourself: > > <?php > > $copies = array(); > $string = str_repeat( '*', 1000000 ); > > echo memory_get_usage()."\n"; > for( $i = 0; $i < 1000; $i++ ) > { > Â Â $copies[] = $string; > } > echo memory_get_usage()."\n"; > > ?> > > Cheers, > Rob. > -- > http://www.interjinn.com > Application and Templating Framework for PHP > > -- > PHP General Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > > -- <hype> WWW: http://plphp.dk / http://plind.dk LinkedIn: http://www.linkedin.com/in/plind Flickr: http://www.flickr.com/photos/fake51 BeWelcome: Fake51 Couchsurfing: Fake51 </hype>
From: Robert Cummings on 16 Mar 2010 12:10 Peter Lind wrote: > This is one example where references actually decrease memory usage. > The main reason is the recursive nature of the function. Try > > <?php > > echo memory_get_usage() . PHP_EOL; > $array = range(0,1000000); > $array[10] = range(0,10); > $array[20] = range(0,10); > $array[30] = range(0,10); > $array[40] = range(0,10); > $array[50] = range(0,10); > $array[60] = range(0,10); > $array[70] = range(0,10); > $array[80] = range(0,10); > $array[90] = range(0,10); > $array[100] = range(0,10); > echo memory_get_usage() . PHP_EOL; > carray($array); > function carray ($array) > { > foreach ($array as $value) > { > if (is_array($value)) carray($value); > } > echo memory_get_usage() . PHP_EOL; > echo count($array) . PHP_EOL; > } > echo memory_get_usage() . PHP_EOL; > > And then compare with: > > <?php > > echo memory_get_usage() . PHP_EOL; > $array = range(0,1000000); > $array[10] = range(0,10); > $array[20] = range(0,10); > $array[30] = range(0,10); > $array[40] = range(0,10); > $array[50] = range(0,10); > $array[60] = range(0,10); > $array[70] = range(0,10); > $array[80] = range(0,10); > $array[90] = range(0,10); > $array[100] = range(0,10); > echo memory_get_usage() . PHP_EOL; > carray($array); > function carray (&$array) > { > $i = 0; > foreach ($array as $value) > { > if (is_array($value)) carray($value); > } > echo memory_get_usage() . PHP_EOL; > echo count($array) . PHP_EOL; > } > echo memory_get_usage() . PHP_EOL; > > The memory usage spikes in the first example when you hit the second > array level - you don't see the same spike in the second example. > > Regards > Peter Doh, forgot about that :) Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: how to get the local time Next: Spreadsheet_Excel_Reader problem |