codeinphp Posted February 25, 2016 Share Posted February 25, 2016 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. Quote Link to comment Share on other sites More sharing options...
Psycho Posted February 25, 2016 Share Posted February 25, 2016 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"; } Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted February 25, 2016 Share Posted February 25, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
codeinphp Posted February 25, 2016 Author Share Posted February 25, 2016 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. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted February 25, 2016 Share Posted February 25, 2016 (edited) from your last thread, you have the $data array. foreach($data as $time=>$arr) { // $time is the main array index time value // $arr is an array of the arrays of data under that time - do whatever you want with it here. } Edited February 25, 2016 by mac_gyver Quote Link to comment Share on other sites More sharing options...
Psycho Posted February 25, 2016 Share Posted February 25, 2016 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>"; } } } } Quote Link to comment Share on other sites More sharing options...
codeinphp Posted February 26, 2016 Author Share Posted February 26, 2016 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 Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted February 26, 2016 Share Posted February 26, 2016 (edited) 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 February 26, 2016 by mac_gyver Quote Link to comment Share on other sites More sharing options...
Solution codeinphp Posted February 26, 2016 Author Solution Share Posted February 26, 2016 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; } Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.