Web Analytics Made Easy -
StatCounter count on specific dimension in multidimesional array - CodingForum

Announcement

Collapse
No announcement yet.

count on specific dimension in multidimesional array

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • count on specific dimension in multidimesional array

    I have a 5-dimensional array and i would need to have a count of the elements in the 4° dimension. Is this possible? And how?

    My current hack is that i include the count as an element in the 3° dimension, but this has obvious disadvantages (like when i push in another element in the 4° dimension, this countvalue in the 3° dimension isn't automatically updates, so i would then always need to alter that value which is to risky)
    Posting guidelines I use to see if I will spend time to answer your question : http://www.catb.org/~esr/faqs/smart-questions.html

  • #2
    You are correct. What you are using now is a terrible hack.
    And it's certainly possible to count elements of the 4th dimension. After toying a little with control structures, I came up with the following:

    PHP Code:
    function recursiveCount(&$array$dimension) {
        if (
    $dimension == 0) {
             return 
    count($array);    
        }
        
        
    $count 0;
        while (list(, 
    $value) = each($array)) {
             
    $count += recursiveCount($value$dimension 1);
        }
        return 
    $count;        
    }


    $test = array();
    $test[0][0][0][0][] = 'bar';
    $test[0][0][0][0][] = 'bar1';
    $test[0][0][0][0][] = 'bar2';
    $test[0][0][0][1][] = 'foo';
    $test[0][0][0][1][] = 'foo1';


    print 
    recursiveCount($test4); 
    Hope that helps, I wasn't quite sure about the test array, if the number of dimensions is correct, I always get confused by working with 0-indexed arrays and numbering them like human would (first dimension etc.)
    De gustibus non est disputandum.

    Comment


    • #3
      Thanks mordred.

      Hmm. Doesn't work for my particular situation. I now realise that not all element of the 3°dimension are arrays so i need to take out all these elements, or else i got this
      "Warning: Variable passed to each() is not an array or object in"-error

      I was making my code way to complex to avoid an extra itertion, but i've now rewriten parts of the code to make it more modular and simpler. I will now be iterating through the arrays 1°dimension-elements. So I would actually only need the count of the elements in for instance $hcr[$i]['prop']['cols']

      I currently use
      PHP Code:
      foreach ($hcr[$i]['prop']['cols'] as $column){
          
      $colcount ++ ;

      which seems to be working (takes 0.00236 secs for 10 elements)

      Any ideas on doing this without the extra foreach() ?
      Posting guidelines I use to see if I will spend time to answer your question : http://www.catb.org/~esr/faqs/smart-questions.html

      Comment


      • #4
        Hey raf, it really sounds as if your code is too complex. Maybe using a tree-like object would be more suited for your needs? Just guessing because I don't know the details of your data structure, and it's usage.

        But you can work around the "variable is not an array" problem easily:

        Code:
        function recursiveCount(&$array, $dimension) {
        	if ($dimension == 0) {
        		 return count($array);	
        	}
        	
        	$count = 0;
        	while (list(, $value) = each($array)) {
        		[b]if (is_array($value)) {[/b]
        			$count += recursiveCount($value, $dimension - 1);    
        		[b]}[/b] 	
        	}
        	return $count;		
        }
        The new code is in bold letters. The function above would only take into account those elements of the dimension level to search for.

        I did not get the part concerning the foreach loop. Where would that fit into my code, can you post an example? And if it's feasible, can you also post a tiny excerpt of your data structure you want to count, so I get a better idea where the pitfalls are?

        If you're concerned about performance of the counting routine, keep in mind that foreach() makes a copy of the array to be counted. Sad but true.
        De gustibus non est disputandum.

        Comment


        • #5
          Originally posted by mordred
          Hey raf, it really sounds as if your code is too complex. Maybe using a tree-like object would be more suited for your needs Just guessing because I don't know the details of your data structure, and it's usage. ? ... And if it's feasible, can you also post a tiny excerpt of your data structure you want to count, so I get a better idea where the pitfalls are?
          Ok. I didn't want to give any backgroundinfo because it's just a small part of a complex scripts.
          Some background:
          Im writing a page that is part of a module to create a pdf file from a db. It's part of a completely generic web-application. In this part, the users specifyes which data need to be selected from which tables, and where it should come in the pdf. (so he defines both the layout and data of the pdf that will be generated)
          The code generates a 5-dimensional array that contains one 1°dimension element for each pdf-element (like a line, a table, text etc) 2° dimension is then the tile, the data, the propertys etc.
          The array doesn't contain actual values, but placeholders that are replaced by the actual values (selected at runtime from the db)

          The page with the troubeling section --> it's a page that generates the pdf at runtime. So it takes in this filled in 5-d array and then i am looping through it to transform each element into a piece of pdf.

          So i can't actually give you an example of the arrays i'm working on. But an element of the array looks like
          PHP Code:
          $hcr[1]['type']= 'tablesimple';
          $hcr[1]['spacer']= 0;
          $hcr[1]['prop']= array('startx'=>$tx,'widthtable'=>$w,
                          
          'cols'=>array(array('label','left',($txx $tx)),
                                        array(
          'value','left',($w $txx $tx ))
                                        )
                                 );
          $hcr[1]['data']= array(array('label'=>'Name''value'=>'Bill')); 
          (the variables are part of the template to determine the width etc of the table)

          This all works fine for regular content, but the tricky bit are tables with 'merged cells'. This is apparently not possible for pdf's unless you kinda fake it to look like a table with merged cells.

          So for these tables, i create a seperate 5-d array an some seperate code, where i kinda stick regular tables, lines and filled rectangles together to get this 'merged cells' effect.

          I wanted to get a count of the total number of column, so that i can create a label for each column of that table. So that i need to loop only once through the array to get all column-labels.
          So if i want to do this in a for() loop, i need to have a terminating value --> the total column count.

          (Note : i could of course use a very high value and then run a check inside the loop to see if that key is outside the key-range and break; if it is, but that's not realy efficient)
          Originally posted by mordred
          I did not get the part concerning the foreach loop. Where would that fit into my code, can you post an example? And if it's feasible, can you also post a tiny excerpt of your data structure you want to count, so I get a better idea where the pitfalls are?
          Euh. I think i didn't explian clearly enough in my previous post.
          I've changed the arraystructure and my code, and now, i loop through the array, processing it one element (1° dimension) at a time.
          If i have an element (like the simple table), then i need to get he number of columns. So that is why i use the foreach() to get the count. I then use it inside a for() loop to build the pdf-column
          Originally posted by mordred
          If you're concerned about performance of the counting routine, keep in mind that foreach() makes a copy of the array to be counted. Sad but true.
          I know. That's why i would like to try and avoid it and get the count in a more efficient way then this.
          The complete operation (getting the code that needs to be executed from the db, getting the data to use inside the code, building the pdf's, attaching them to a mail and sending them) takes about 4.6 to 5.2 seconds, so i want to optimize it as much as possible.

          I agree that the code and arrays are complex (at least, explaining about them is), but it are complex processes i need for this feature. After all, i now only need 15 lines of code to transform the arrays into a pdf-table, 1 select to get all data etc.

          Thanks for your input, but at the moment, i've abandonned the recursive count for the complete dimension because i'm building the table different now. I've made a note to revise the code that generate the array, to see if i can include a count there and store it in an array (the number of columns for each table so that i can do $collcount[$i] to get the count). It could be more efficient...

          Thanks again
          Posting guidelines I use to see if I will spend time to answer your question : http://www.catb.org/~esr/faqs/smart-questions.html

          Comment

          Working...
          X