Jump to content

Compile an array based on other arrays


codeinphp
Go to solution Solved by codeinphp,

Recommended Posts

Trying to build an array from elements taken from another array, which I thought would be easy but not so much. My first step is to create a $control that will be used in a loop later on.  I am then looping thru an array file comparing an element's value to the $control.  If the same, for testing I am sending it to browser.  In code below, $control is already created.  The array file I am looping thru has the following structure:

$items=array (
  0 => 
  array (
    'time' => '201601221400',
    'title' => 'FABLife',
    'desc' => 'Mark Cuban (``Shark Tank\'\'); top five must-haves; collectors try to guess the prices of celebrity memorabilia; creating a high-end playroom and eliminating toy clutter without breaking the bank.',
  ),
  1 => 
  array (
    'time' => '201601221400',
    'title' => 'The First 48',
    'desc' => 'A young man is robbed and killed while meeting up with a girl he met earlier; a man is gunned down outside an annual football game.',
  ),
  2 => 
  array (
    'time' => '201601221400',
    'title' => 'Teen Titans Go!',
    'desc' => 'Robin makes the other Titans sell their treasured mementos from past adventures.',
  ),

Note: The number of 'time' elements vary as tho how many have the same value. In the example I posted this particular time element has 3 of the same value, some have more some have less.  I want to loop thru the array file, compare the $control to the 'time' value, if equal it will echo to browser. I want the loop to continue  for either as long as the $control and 'time' are equal or 5 is reached.

for($i=0; $i< count($control); $i++){
foreach ($items as $item){
		while (($items['time']==$control[$i]) || ($r < 5 )){
				if ($r > 5){
                                echo "OUT. . ."."<BR>";
				$r=0;
                                
				}else{
				$r=$r+1;		
				echo $control[$i]."  ". $r."<br>";
				
					}
				}
			}
			
		}	

When this is ran, I get the first 5 values of the first 'time' but then nothing, it's not continuing to the next $control. Can somebody point out my error(s)?  Thanks.

Link to comment
Share on other sites

I don't know what the source of your data is, but based on what you need to do they could be structured in a much better format. If you are the one building these arrays you should fix that. If this data is coming from a database, you shouldn't need to build these arrays at all.

 

As to your code, it is simply illogical. It's not worth my time to try and break it down and explain why it doesn't work.

 

 

//Create array to hold all the found matches
$foundValues = array();
//Iterate over each control value
foreach($control as $controlVal)
{
    //Iterate over each item record
    foreach($items as $itemVal)
    {
        //Check for a match and append to found array
        if($controlVal == $itemVal['time'])
        {
            $foundValues[] = $controlVal;
        }
        //Break the current loop if found count is 5
        if(count($foundValues)==5) { break; }
    }
    //Break the current loop if found count is 5
    if(count($foundValues)==5) { break; }
}
 
//Output the results
foreach($foundValues as $index => $value)
{
    $number = $index + 1;
    echo "{$value} {$number}<br>\n";
}
if(count($foundValues)==5)
{
    echo "OUT. . . <br>\n";
}
Link to comment
Share on other sites

so, what you are trying to do is output a maximum of 5 sets of data for each time value?

 

if so, i would just loop over the result you got from your last thread on the forum, which would give the time and an array of the data for that time, and output the data the way you want it. you can use array_slice() to get a maximum of 5 elements from the array under each time value, then just implode or loop over that array, depending on how complex the formatting is, and echo the result.

  • Like 1
Link to comment
Share on other sites

Thanks for the advice.  Psycho, not sure what you mean as to the structure of the array, I thought it was pretty straight forward, one array with three element (time, title, desc).  Not going to argue at all about it but I thought my logic kinda follows what you did, of course yours is better since it works. Thank you for you input.  Mac_gyver, that's kinda what I wanted to do but I couldn't figure out how to move to next "new" time value in the loop, or get it to move. 

Thanks to both for the help.

Link to comment
Share on other sites

Psycho, not sure what you mean as to the structure of the array, I thought it was pretty straight forward, one array with three element (time, title, desc).

You should not have to do nested loops to get the data you need. This is very inefficient. As I said, if you are generating this data, then you can put them in a more logical format for your needs. Yes, the data is straight forward - for a human to read. But, the fact that a nested loop is needed should be a red flag that it is not the right format. For example, since the time value is so important, the time value could be the index for the array values and the values could be sub-arrays of the records with their title & desc. Then you don't even need a loop, let alone nested loops. E.g.

 

$items=array (
  '201601221400' => 
  array (
    array (
      'title' => 'FABLife'
      'desc' => 'Mark Cuban (``Shark Tank\'\'); top five must-haves; collectors try to guess the prices of celebrity memorabilia; creating a high-end playroom and eliminating toy clutter without breaking the bank.'
      ),
    array (
      'title' => 'The First 48',
      'desc' => 'A young man is robbed and killed while meeting up with a girl he met earlier; a man is gunned down outside an annual football game.',
      ),
    array (
      'title' => 'Teen Titans Go!',
      'desc' => 'Robin makes the other Titans sell their treasured mementos from past adventures.',
      )
    )
  ),
  '201601221600' => 
  array (
    array (
      'title' => 'Some other Title'
      'desc' => 'Some other description'
      )
  )
);

 

But, as I also said, if this is coming from a database, then you shouldn't need arrays at all. But, you have not provided enough data to know what the best method really is since all we have to go on is the arrays you've provided.

 

 

 . . .  but I thought my logic kinda follows what you did, of course yours is better since it works. 

 

Not really. Your code had several flaws. Here is your code with comments. There are two major flaws indicated with '***'. I suggest you write comments with your code as it can help you identify logic errors.

 

//Create a loop for the number of elements in $control
for($i=0; $i< count($control); $i++)
{
    //Loop through each instance of $items
    foreach ($items as $item)
    {
        //Run a while() loop as long as the current $item['time'] matches the $control[$i] value at $i
        //And $r is less than 5
        //**** Assuming this condition is ever true, the while() loop will be repeated
        //     for THE EXACT SAME $item['time'] and $control[$i] values until $r = 5
        //     because there is no logic in the loop to iterate to the next $time record
        //     or increment $i
        While (($items['time']==$control[$i]) || ($r < 5 ))
        {
            //Check if $r > 5
            //**** THIS IS IMPOSSIBLE DUE TO THE WHILE CONDITION ABOVE
            if ($r > 5)
            {
                echo "OUT. . ."."<BR>";
                $r=0;
            }
            else
            {
                $r=$r+1; 
                echo $control[$i]."  ". $r."<br>";
            }
        }
    }
} 
Link to comment
Share on other sites

Psycho, you are correct in that the array needed to be restructured.  I have done this and have the script running as needed. Thanks for the advice but either I didn't communicate my idea well or it was was just not understood. In your solution you break if the count of the $foundvalues==5. This is no good, it will only break for the first array then the count will be more than five.  The $foundvalues is never reset so it's count will always be more than 5,  correct?  I replaced checking the count of the array with a counter that increments by 1.  When it reaches 5 it breaks and resets.  This gives me exactly what is needed, the first 5 arrays of each array.  Thanks again

Link to comment
Share on other sites

untested, but should work -

// the code given in your last thread -
$data = array();
foreach($items as $arr){
    $data[$arr['start']][] = $arr; // index/pivot the data using the start datetime as the key
}
 
 
// the suggested processing in this thread -
foreach($data as $time=>$arr){
    echo "$time<br>"; // output a heading
    $arr = array_slice($arr, 0, 5); // get a maximum of 5 elements from the array
    foreach($arr as $element){
        echo "Title: {$element['title']}, Description: {$element['desc']}<br>"; // output the data the way you want
    }
}
Edited by mac_gyver
Link to comment
Share on other sites

  • Solution

Thank you both for the advice and direction. After restructure of the array into.  I'm sure it can be cleaner but I don't know a lot about PHP, only what I have read or found on forums.  

 0 => 
  array (
    'start' => '201601221400',
  ),
  1 => 
  array (
    'time' => '201601221400',
    'name' => 'ABC',
    'title' => 'FABLife',
    'desc' => 'Mark Cuban (``Shark Tank\'\'); top five must-haves; collectors try to guess the prices of celebrity memorabilia; creating a high-end playroom and eliminating toy clutter without breaking the bank.',
  ),

I was able to parse as needed with the following:

$counter=0;
//CONTROL
foreach ($items as $key=>$value){
		echo "NEW CONTROL   ".$value['start']."<br>";
		
		foreach ($items as $item=>$time){
						
	 	if($time['time']==$value['start']){
					
				if(empty($time['time'])){
					}else{
						$counter=$counter + 1;
						$match[]=array(
						'time'=>$time['time'],
						'title'=>$time['title'],
						'desc'=>$time['desc'],
						);
					
						if ($counter==5){break;}
									
							if ($counter==5){break;}	
							
							}	
						}	
							}		
						$counter=0;
                                }
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.