Check ahead in array

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Check ahead in array

Post by Skittlewidth »

I'm posting in the hope that whilst typing this out the solution will come to me as it usually does. Rest assured I will be working on this after I have posted and won't just sit here waiting for an answer!

I have an array of arrays. e.g

Code: Select all

$qlist = array(
       array("What is your name?", "false"),
       array("What is your age?", "true"),
       array("What is your hair colour", "true"),
       array("What is your favourite food?", "false"),
       array("Do you like cheese", "true"),
       array("Do you have a tv?", "false"),
       array("Do you drink?", "false"),
       ...............etc
)
The second element in the array denotes whether a question is a sub question (true) or the start of a new block of questions (false).

Say I want to display 3 main questions at a time. I will want to display all the subquestions that go with it.

In my head the logic is something like this:

Code: Select all

start a loop

echo the first question

look at the next question in the array to see if it is a subquestion

     if yes:
          echo the subquestion 
          look at the next question in the array to see if it is a subquestion
                      if yes:
                            echo the subquestion 
                            look at the next question in the array to see if it is a subquestion  etc etc

     if no:
          next loop until 3 main questions have been displayed
My main headache is how to look forward for the subquestions infinitely until it finds the next question that isn't.

I think it may involve a while loop and next() but I'm not sure and I'm feeling like a complete noob again all of a sudden.

Must have taken too many blows to the head whilst snowboarding last week :wink:

Will continue to experiment in the meantime....
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

something like this?

Code: Select all

$falses = 0;
for($i = 0, $j = count($qlist); $i < $j and $falses < 4; $i++)
{
  echo $qlist[$i][0] . "\n";
  if($qlist[$i][1] == 'false')
  {
    $falses++;
  }
}
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

Thanks Feyd, I'd just figured it out by the time I saw your post.

Code: Select all

$q_array = array(
				array("Question 1", ""),
				array("Question 1.1", "sub"),
				array("Question 1.2", "sub"),
				array("Question 2", ""),
				array("Question 2.1", ""),
				array("Question 3", ""),
				array("Question 4", ""),
				array("Question 5", ""),
				array("Question 6", ""),
				array("Question 6.1", "sub"),
				array("Question 6.2", "sub"),
				array("Question 6.3", "sub"),
				array("Question 6.4", "sub"),
				array("Question 7", ""),
				array("Question 8", "")
			);


function Showqs($qlist, $offset, $limit){
	
	$i = $offset;
	$loopcount = 0;
	
	while ($loopcount <=$limit){		
		echo $qlist[$i][0]."<br/>";
		
		$next = $i+1; //look forward
		$remainder = count($qlist) - $next; //rest of the array
		
		for ($j=$next; $j <=$remainder; $j++){
			if ($qlist[$j][1] =="sub"){
				echo "---".$qlist[$j][0]."<br/>";
			}
			else{
				$i = $j; //need to update the array pointer for the next WHILE loop
				$loopcount ++;
				break 1;
			}
		}
	}
	return $i; //return the number of the final element so you know where to start the next offset.
}

$result = Showqs($q_array, 2, 4);
This seems to work, but there is a bug in it somewhere which causes an infinite loop when the code goes over the fifth element in the array. I'm sure I'll spot it in a minute though.
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

Erg... I'm still having problems here. I've modified the code a bit, and taken out the for loop because one of the comments on php.net for for loops stated that you couldn't access a variable outside the scope of the for loop, where as you can with a while loop.

I need to pass the value of the counter from the inner while loop to the outer while loop at the point that the inner loop breaks. Then when the outer loop goes through its next rotation $i is at the point that the inner loop left off.

As I stated before this works fine for the first 4 main questions with its associated sub questions. But if you change the offset or limit so that it gets to question five (element 7 in the array) it enters an infinite loop because it appears to avoid entering the second while loop. But why?

Question 5 is followed by a non-sub question, but then so are questions 3 and 4 and they had no issues.

The code below is set to display the first 4 questions and their subs. It will return the index of the next item in the array for continuation purposes later. Can anyone tell me why the 7th element ignores the while loop?

Code: Select all

$q_array = array(
				array("Question 1", ""),
                array("Question 1.1", "sub"),
                array("Question 1.2", "sub"),
                array("Question 2", ""),
                array("Question 2.1", "sub"),
                array("Question 3", ""),
                array("Question 4", ""),
                array("Question 5", ""),
                array("Question 6", ""),
                array("Question 6.1", "sub"),
                array("Question 6.2", "sub"),
                array("Question 6.3", "sub"),
                array("Question 6.4", "sub"),
                array("Question 7", ""),
                array("Question 8", "") 
			);


function Showqs($qlist, $offset, $limit){
	
	$i = $offset;
	$loopcount = 0;
	$notsub=0;

	while ($loopcount < $limit){		
		echo $qlist[$i][0]."<br/>";
			
		$next = $i+1; //look forward
		$remainder = count($qlist) - $next;
		
		while ($next < $remainder){
			if ($qlist[$next][1] == "sub"){
				echo "---".$qlist[$next][0]."<br/>";
				$next++;
				echo "This is a sub!<br/>";
			}
			elseif ($qlist[$next][1] == ""){
				$i = $next; //need to update the array index for the next WHILE loop
				echo "This is NOT a sub!<br/>";
				$loopcount++;
				break 1;
			}
		}
		echo "<b>Next = ".$i."</b><br/>";
		
	}
	return $i;
}

$result = Showqs($q_array, 0, 4);
echo "result: ".$result;
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

did you try my code with the original data?
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

Yes I did, and as beautifully simple as it is, it won't display all the subquestions if the loop ends on a main question that has them, because it doesn't look forward to check:

eg.

Code: Select all

$qlist = array(
                array("Question 1", ""),
                array("Question 1.1", "sub"),
                array("Question 1.2", "sub"),
                array("Question 2", ""),
                array("Question 2.1", ""),
                array("Question 3", ""),
                array("Question 4", ""),
                array("Question 5", ""),
                array("Question 6", ""),
                array("Question 6.1", "sub"),
                array("Question 6.2", "sub"),
                array("Question 6.3", "sub"),
                array("Question 6.4", "sub"),
                array("Question 7", ""),
                array("Question 8", "")
            );




$falses = 0;
for($i = 0, $j = count($qlist); $i < $j and $falses < 7; $i++)
{
  echo $qlist[$i][0] . "\n<br/>";
  if($qlist[$i][1] != 'sub')
  {
    $falses++;
  }
}
returns:

Code: Select all

Question 1 
Question 1.1 
Question 1.2 
Question 2 
Question 2.1 
Question 3 
Question 4 
Question 5 
Question 6
I'll have a go at adapting your code further since I've reached a dead end with mine, but just for my own sanity could you explain why that array element was avoiding that while loop in my previous post?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Code: Select all

<?php

$qlist = array(
	array("Question 1", ""),
	array("Question 1.1", "sub"),
	array("Question 1.2", "sub"),
	array("Question 2", ""),
	array("Question 2.1", ""),
	array("Question 3", ""),
	array("Question 4", ""),
	array("Question 5", ""),
	array("Question 6", ""),
	array("Question 6.1", "sub"),
	array("Question 6.2", "sub"),
	array("Question 6.3", "sub"),
	array("Question 6.4", "sub"),
	array("Question 7", ""),
	array("Question 8", "")
);

$falses = 0;
$limit = 6;
for($i = 0, $j = count($qlist); $i < $j and $falses <= $limit+1; $i++)
{
  if($qlist[$i][1] != 'sub')
  {
    $falses++;
  }
  if($falses <= $limit+1)
  {
    echo $qlist[$i][0] . "\n";
  }
}

?>
outputs

Code: Select all

Question 1
Question 1.1
Question 1.2
Question 2
Question 2.1
Question 3
Question 4
Question 5
Question 6
Question 6.1
Question 6.2
Question 6.3
Question 6.4
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

Brilliant Feyd, thanks. It's so simple it took me a few moments to understand how it was doing what it was doing.
Now why couldn't I have come up with that in the first place? I was so stumped before that I drew logic diagrams and everything! :roll:
Post Reply