Re: [PHP] Need routine to tell me number of dimensions in array.
On 17 March 2010 01:10, Robert Cummings wrote: > > Rene Veerman wrote: >> >> maybe you should be foreach()ing with references? >> php.net : search "foreach" : >> >> >> As of PHP 5, you can easily modify array's elements by preceding >> $value with &. This will assign reference instead of copying the >> value. >> > $arr = array(1, 2, 3, 4); >> foreach ($arr as &$value) { >> $value = $value * 2; >> } >> // $arr is now array(2, 4, 6, 8) >> unset($value); // break the reference with the last element >> ?> >> This is possible only if iterated array can be referenced (i.e. is >> variable), > > References in foreach don't work the way you think they work. You will still > incur the copy. At least I did when I tested earlier today :) > > 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 > > The peak memory usage when using references (or not) and using foreach() vs array_walk() was the same in all my testing. But surprisingly, the foreach() with references all round used the lowest memory during the looping. The worse case was mixing reference and value passing with array_walk(). My dataset was generated by reading the C:\PHP5 directory where the keys are the directories and saving the data as an include (var_export()-ing it). RIchard. -- - 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 -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Need routine to tell me number of dimensions in array.
Rene Veerman wrote: maybe you should be foreach()ing with references? php.net : search "foreach" : As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value. This is possible only if iterated array can be referenced (i.e. is variable), References in foreach don't work the way you think they work. You will still incur the copy. At least I did when I tested earlier today :) 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
Re: [PHP] Need routine to tell me number of dimensions in array.
maybe you should be foreach()ing with references? php.net : search "foreach" : As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value. This is possible only if iterated array can be referenced (i.e. is variable), On Tue, Mar 16, 2010 at 5:43 PM, Robert Cummings wrote: > Peter Lind wrote: >> >> Hmm, will probably have to look inside PHP for this ... the foreach >> loop will copy each element as it loops over it (without actually >> copying, obviously), however there's no change happening to the >> element at any point and so there's nothing to suggest to the >> copy-on-write to create a new instance of the sub-array. >> >> It should look like this: >> $a = array(0, 1, 2, array(0, 1, 2, 3), 4, 5, 6, n); >> $b = $a[3]; >> doStuffs($b); >> >> Whether or not you loop over $a and thus move the internal pointer, >> you don't change (well, shouldn't, anyway) $b as that's a subarray >> which has it's own internal pointer, that isn't touched. >> >> Or maybe I've gotten this completely backwards ... > > I'm not sure of the exact reason... PHP has the following comment: > > Note: Unless the array is referenced, foreach operates on a copy > of the specified array and not the array itself. foreach > has some side effects on the array pointer. Don't rely on > the array pointer during or after the foreach without > resetting it. > > http://php.net/manual/en/control-structures.foreach.php > > I've always found the foreach loop to a be a bit on the bizarre size, this > is probably just another one of those bizarrities :) > > 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 > > -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Need routine to tell me number of dimensions in array.
Peter Lind wrote: Hmm, will probably have to look inside PHP for this ... the foreach loop will copy each element as it loops over it (without actually copying, obviously), however there's no change happening to the element at any point and so there's nothing to suggest to the copy-on-write to create a new instance of the sub-array. It should look like this: $a = array(0, 1, 2, array(0, 1, 2, 3), 4, 5, 6, n); $b = $a[3]; doStuffs($b); Whether or not you loop over $a and thus move the internal pointer, you don't change (well, shouldn't, anyway) $b as that's a subarray which has it's own internal pointer, that isn't touched. Or maybe I've gotten this completely backwards ... I'm not sure of the exact reason... PHP has the following comment: Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it. http://php.net/manual/en/control-structures.foreach.php I've always found the foreach loop to a be a bit on the bizarre size, this is probably just another one of those bizarrities :) 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
Re: [PHP] Need routine to tell me number of dimensions in array.
Hmm, will probably have to look inside PHP for this ... the foreach loop will copy each element as it loops over it (without actually copying, obviously), however there's no change happening to the element at any point and so there's nothing to suggest to the copy-on-write to create a new instance of the sub-array. It should look like this: $a = array(0, 1, 2, array(0, 1, 2, 3), 4, 5, 6, n); $b = $a[3]; doStuffs($b); Whether or not you loop over $a and thus move the internal pointer, you don't change (well, shouldn't, anyway) $b as that's a subarray which has it's own internal pointer, that isn't touched. Or maybe I've gotten this completely backwards ... Regards Peter On 16 March 2010 17:12, Robert Cummings wrote: > Peter Lind wrote: >> >> This is one example where references actually decrease memory usage. >> The main reason is the recursive nature of the function. Try > > BTW, it's not the recursive nature of the function causing the problem. It's > the movement of the internal pointer within the array. When it moves the COW > realizes the copy's pointer has moved and splits off the copy. You can > verify this by echoing the memory usage when you first enter carray(). The > spike occurs inside the foreach loop. > > 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 > > -- 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 -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Need routine to tell me number of dimensions in array.
Peter Lind wrote: This is one example where references actually decrease memory usage. The main reason is the recursive nature of the function. Try BTW, it's not the recursive nature of the function causing the problem. It's the movement of the internal pointer within the array. When it moves the COW realizes the copy's pointer has moved and splits off the copy. You can verify this by echoing the memory usage when you first enter carray(). The spike occurs inside the foreach loop. 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
Re: [PHP] Need routine to tell me number of dimensions in array.
Peter Lind wrote: This is one example where references actually decrease memory usage. The main reason is the recursive nature of the function. Try Doh, forgot about that :) 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
Re: [PHP] Need routine to tell me number of dimensions in array.
This is one example where references actually decrease memory usage. The main reason is the recursive nature of the function. Try wrote: > > > Richard Quadling wrote: >> >> On 15 March 2010 23:45, Daevid Vincent 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: > > > $copies = array(); > $string = str_repeat( '*', 100 ); > > 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 > > -- 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 -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Need routine to tell me number of dimensions in array.
Richard Quadling wrote: On 15 March 2010 23:45, Daevid Vincent 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: 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
Re: [PHP] Need routine to tell me number of dimensions in array.
On 15 March 2010 23:45, Daevid Vincent 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 -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Need routine to tell me number of dimensions in array.
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 I am working with the following data structure 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}"; ?> http://www.cmsws.com/examples/php/testscripts/dae...@daevid.com/0002.php Globals are dirty for this kind of recursive utility function. Here's a cleaner example: $maxDepth ) { $maxDepth = $subDepth; } } return 1 + $maxDepth; } ?> 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
Re: [PHP] Need routine to tell me number of dimensions in array.
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 I am working with the following data structure 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}"; ?> http://www.cmsws.com/examples/php/testscripts/dae...@daevid.com/0002.php -- Jim Lucas NOC Manager 541-323-9113 BendTel, Inc. http://www.bendtel.com -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Need routine to tell me number of dimensions in array.
On Mon, 2010-03-15 at 17:23 -0700, Daevid Vincent wrote: > Oh. I know it's not a simple solution to do right Ashley. And exacerbated > by the fact that each array dimension can have different dimensions as > well. This is why I wanted someone else's solution first before I spend > hours or days on one that works reliably. :) > > > _ > > From: Ashley Sheridan [mailto:a...@ashleysheridan.co.uk] > Sent: Monday, March 15, 2010 4:44 PM > Subject: Re: [PHP] Need routine to tell me number of dimensions in array > > The only way to do it reliably would be to iterate the entire array, > element by element, as all the elements of an array might not necessarily > be all of the array type or int's. > > Best way I can think of is to iterate the entire thing and keep a count as you do. I'm not aware of any functions that can do what you need there. Thanks, Ash http://www.ashleysheridan.co.uk
RE: [PHP] Need routine to tell me number of dimensions in array.
Oh. I know it's not a simple solution to do right Ashley. And exacerbated by the fact that each array dimension can have different dimensions as well. This is why I wanted someone else's solution first before I spend hours or days on one that works reliably. :) _ From: Ashley Sheridan [mailto:a...@ashleysheridan.co.uk] Sent: Monday, March 15, 2010 4:44 PM Subject: Re: [PHP] Need routine to tell me number of dimensions in array The only way to do it reliably would be to iterate the entire array, element by element, as all the elements of an array might not necessarily be all of the array type or int's.
Re: [PHP] Need routine to tell me number of dimensions in array.
On Mon, 2010-03-15 at 16:45 -0700, 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"... > > Array > ( > [0] => Array > ( > [0] => Data marked as faulty or timestamps before 2005 or in > the future (2035) > [1] => bad_data > ) > > [1] => Array > ( > [0] => Hardware Part Numbers > [1] => hardware_part_numbers > ) > > [2] => Array > ( > [0] => Software Part Numbers > [1] => software_part_numbers > ) > > [3] => Array > ( > [0] => Software Version Number > [1] => software_version_numbers > ) > > [4] => Array > ( > [0] => Configuration Part Numbers > [1] => configuration_part_numbers > ) > > ) > > From a programatic POV, it's not quite that easy to see "this is a THREE > dimensional", since element [0][0] is missing and it actually starts at > [0][1], so you can't do an is_array($foo[0][0]) on it (but if you did on > [0][1] it would pass) so you have to itterate over ALL elements of the > array until you find one that hits or you exhaust that dimension. But then > you have to traverse any subdimensions too, most likely recursively. > > Array > ( > [0] => Array > ( > [1] => Array > ( > [0] => Aircraft Registration > [1] => aircraft_registration > ) > > [2] => Array > ( > [0] => Aircraft Type-Subtype > [1] => aircraft_type_subtype > ) > > [3] => Array > ( > [0] => System > [1] => system_type_name > ) > > [4] => Array > ( > [0] => Flight Count > [1] => flight_count > ) > > ... > > > Then it gets even more complex as this has all sorts of holes in it... > > Array > ( > [0] => Array > ( > [0] => Array > ( > [0] => Flight Number > [1] => flight_number > ) > > [4] => Array > ( > [0] => Timestamp Departure > [1] => timestamp_departure > ) > > [6] => Array > ( > [0] => Timestamp Arrival > [1] => timestamp_arrival > ) > > [8] => Array > ( > [0] => Departure City > [1] => departure_city > ) > > [9] => Array > ( > [0] => Arrival City > [1] => arrival_city > ) > > Now I could take the time to dig in and figure this all out, but I thought > maybe someone already had a solution they could share? > > The only way to do it reliably would be to iterate the entire array, element by element, as all the elements of an array might not necessarily be all of the array type or int's. Thanks, Ash http://www.ashleysheridan.co.uk