Cycle thru a PHP Array to find the lowest KEY value in each group of five.

I have a php array that looks like this:

$arr = 
array ( 
[1] => 2018-01-25 20:45:16 
[2] => 2018-01-16 16:33:48 
[3] => 2018-01-19 14:41:44 
[8] => 2018-01-23 15:32:52 
[16] => 2018-01-25 05:02:28 
[18] => 2018-01-31 10:44:26
[19] => 2018-01-25 21:20:49 
[51] => 2018-01-30 15:53:53 ) ;

Open in new window


I am looking for the most efficient way to identify the lowest MISSING KEY value in each group of five until we get to 20.

So in the above example, the answers would be:
4
6
11
17

If you had a completely empty array, the answers would be:
1
6
11
16

And if you had one array totally filled:
$arr = 
array ( 
[1] => 2018-01-25 20:45:16 
[2] => 2018-01-16 16:33:48 
[3] => 2018-01-19 14:41:44 
[4] => 2018-01-23 15:32:52 
[5] => 2018-01-25 05:02:28 
[11] => 2018-01-31 10:44:26
[12] => 2018-01-25 21:20:49 
[20] => 2018-01-30 15:53:53 ) ;

Open in new window


The answers would be:

done
6
13
16

As I start thinking about this all I can come up with are very complicated ways of doing it. I would like to tap into the brain power of EE thinkers, to recommend how you would go about approaching this. Maybe it's simple and I'm just not seeing it.

For background this represents a user file for when they signed up for one of 20 main training courses plus a handful of extras (e.g. key values > 20).  Since they can jump around we need to be able to take them back to the next best course to start in each of the four groups of five.  

So if they've done 4 of 5 in group one, we would recommend they do the fifth one next. But if they are jumping all over the place, we want to recommend they go back and do the lowest number over all, or the lowest number in a specific group.

Ask questions if it doesn't make sense.

Thanks.
Paul KonstanskiProject SpecialistAsked:
Who is Participating?
 
Ares KurkluConnect With a Mentor Software EngineerCommented:
You will definitely have to travel thru the array at least once anyway , and  you can have another array to store the empty index values (this can also be a delimited string anyway)

and for every block of 5 (1-5 let's say) once you find an empty one you can store that in the array and jump into the following 5 block
e.g if 2nd one was empty store that and move into the following block as in change the index of the check to 5 and continue the loop.
0
 
Paul KonstanskiConnect With a Mentor Project SpecialistAuthor Commented:
Thanks for the advice. Here is what I came up with:

$lowest = array("A" => 0, "B" => 0, "C" => 0, "D" => 0);
	$themelow = 9999; 
	$totl = 0;
	for ($i = 1; $i <= 20; $i++) {
		if (isset($myplns[$i])) $totl++;
		if ($i <= 5) $grp = "A";
		elseif ($i <= 10) $grp = "B";
		elseif ($i <= 15) $grp = "C";
		elseif ($i <= 20) $grp = "D";
		if ($lowest[$grp] > 0) continue; // if found can skip
		if (!isset($myplns[$i])) $lowest[$grp] = $i;
	} // forloop

Open in new window

0
 
Paul KonstanskiProject SpecialistAuthor Commented:
Thanks Ares for giving me the assurance to proceed as I was thinking.
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

 
NerdsOfTechTechnology ScientistCommented:
Having the data, key mins, and key maxs you could run two for loops with a single break for the first encountered !issset to find 'min available in group'; if no break occurs (no available slot found in group) the min_available_in_group can take on an alternate value (in this case 'done' to indicate no classes are left to take in the particular group):

INPUT:
$arr = 
array ( 
1 =>  '2018-01-25 20:45:16',
2 =>  '2018-01-16 16:33:48',
3 =>  '2018-01-19 14:41:44',
4 =>  '2018-01-23 15:32:52',
5 =>  '2018-01-25 05:02:28',
11 => '2018-01-31 10:44:26',
12 => '2018-01-25 21:20:49', 
16 => '2018-01-25 21:20:49', 
20 => '2018-01-30 15:53:53') ;

$min = array(1, 6, 11, 16);
$max = array(5, 10, 15, 20);

Open in new window


CODE:
$min_available_in_group = $min; // initialize to min

foreach ($max as $k => $v){
	for ($i = $min[$k]; $i <= $max[$k]; $i++){
		if(!isset($arr[$i])){
			$min_available_in_group[$k] = $i;
			break 1;
		}else{
			$min_available_in_group[$k] = $i + 1;
		}
	}
	if($min_available_in_group[$k] > $max[$k]){
		$min_available_in_group[$k] = 'done';
	}
}

Open in new window

OUTPUT:
echo "<pre>";
print_r($min_available_in_group);
echo "</pre>";

/* OUTPUT 

Array
(
    [0] => done
    [1] => 6
    [2] => 13
    [3] => 17
)

*/

Open in new window

0
 
NerdsOfTechTechnology ScientistCommented:
Edit: finalized and tested code (WORKING).
0
 
Paul KonstanskiProject SpecialistAuthor Commented:
One thing I want to do and I'd be curious how to adjust your code.  What I want is to give each of the four groups to have a common name. So rather than have to remember an array of 0,1,2,3 the array will be given keys like "start", "grow", "care", "expand".  So in your above, the desired outcome would be:

[start] => done
[grow] => 6
[care] => 13
[expand] => 17

Open in new window



Is it possible to do that in your above example?
0
 
NerdsOfTechTechnology ScientistCommented:
It's beyond possible:

EDIT: comments added and super_long_variable_name called $min_available_in_group set to $a

<?php
// inputs
$arr = 
array ( 
1 =>  '2018-01-25 20:45:16',
2 =>  '2018-01-16 16:33:48',
3 =>  '2018-01-19 14:41:44',
4 =>  '2018-01-23 15:32:52',
5 =>  '2018-01-25 05:02:28',
11 => '2018-01-31 10:44:26',
12 => '2018-01-25 21:20:49', 
16 => '2018-01-25 21:20:49', 
20 => '2018-01-30 15:53:53') ;

$min = array(1, 6, 11, 16);
$max = array(5, 10, 15, 20);
$a = $min;	// next available number in group range, initialize to minimums

// code
foreach ($max as $k => $v){
	for ($i = $min[$k]; $i <= $max[$k]; $i++){
		if(!isset($arr[$i])){ // if element in group not set, set to the first missing element in range and exit
			$a[$k] = $i;
			break 1;
		}else{ //element found, set to element number +1
			$a[$k] = $i + 1; 
		}
	}
	if($a[$k] > $max[$k]){ // if else from above test set element number above max, then all elements are found in range; thus, set next available to a special value 'done'
		$a[$k] = 'done';
	}
}

$keys = array('start', 'grow', 'care', 'expand');
foreach ($a as $k => $v){
	$temp["$keys[$k]"] = $v; // set key to corresponding key name from $keys
}
$a = $temp; // set temp associative array created from above key assignment loop as new $a array

// output
echo "<pre>";
print_r($a);
echo "</pre>";

/* OUTPUT 

Array
(
    [start] => done
    [grow] => 6
    [care] => 13
    [expand] => 17
)

*/
?>

Open in new window

1
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.