I have a requirement to group the broken series.
//Example
$seriesArray = array(1, 2, 3, 5, 7, 8, 11, 12, 15);
//You see numbers are not continuous here.
//Therefore i need to group the above array to seek the below output
Expected Output
Series 1 : from 1 to 3
Series 2 : 5
Series 3 : 7 and 8
Series 4 : 11 and 12
Series 5 : 15
In the above example, you can see, Series 1 is being grouped from 1 to 3 (as there are greater than 2 values), and in Series 2 and 5, as there is no continuity, showing single value. and in series 3 and 4, it is showing 2 values, with two consecutive values.
What i have tried
function groupSeries($mainArray, $comboArr=array()) {
$getRange = range(min($mainArray), max($mainArray)); //Expected Range
$diffArr = array_diff($getRange, $mainArray); //Difference of what is expected
$ranges = array();
$initiateKey = 0;
foreach($diffArr as $indKey=>$indVal) {
if(!empty($mainArray[$initiateKey])) {
$ranges[] = range($mainArray[$initiateKey], $getRange[$indKey-1]);
$initiateKey = $indKey;
}
}
return showRanges($ranges);
}
function showRanges($getRanges) {
$i = 1;
foreach($getRanges as $indRange) {
$arrCount = count($indRange);
echo "Series $i : ";
switch($arrCount) {
case 1 : echo $indRange[0]; break;
case 2 : echo $indRange[0]." and ".$indRange[1]; break;
default: echo "From ".min($indRange)." to ".max($indRange); break;
}
$i++;
echo "\n";
}
}
$seriesArray = array(1, 2, 3, 5, 7, 8, 11, 12, 15);
groupSeries($seriesArray);
The above series of array is failing with the present output as
Series 1 : From 1 to 3
Series 2 : 5
Series 3 : 8
Series 4 : From 9 to 15
The above trial works with some scenarios, but fails in many.
This should also work –
$seriesArray = array(1, 2, 3, 5, 7, 8, 11, 12, 15);
sort($seriesArray); // Sort array if required
$all = range(min($seriesArray), max($seriesArray)); // get all possibles values in sorted manner
$temp = array_diff($all, $seriesArray); // get the missing values
$new = [];
$i = 1;
foreach ($temp as $missing) {
// Group or extract all values present less than or equals to every missing value to get the series
$new[$i] = array_filter($seriesArray, function($v) use($missing) {
return $v <= $missing;
});
// remove already grouped values
$seriesArray = array_diff($seriesArray, $new[$i]);
$i++;
}
// merge the remaining values or end values & remove empty values
$new = array_filter(array_merge($new, [$seriesArray]));
$new
will have all the grouped values, you can represent as you want.
Answer:
All the checks or tricking around with indexes to access the right elements going on in the other answers still seem a bit convoluted for my tastes, I’d go with
function groupSeries($array) {
$ranges = [];
$idx = -1;
$prev = false;
foreach($array as $val) {
if($prev === false || $val != $prev+1) {
$idx++;
}
$ranges[$idx][] = $val;
$prev = $val;
}
return showRanges($ranges);
}
This really doesn’t need much more, than advancing the index of where to put the value in the result array, based on whether the difference to the previous value is 1 or not.
Answer:
Please have a look at this approch. I hope its not thought to simple. Plese tell me if I missed something:
function groupSeries2($mainArray){
sort($mainArray);
$groups=[];
$group_start=$mainArray[0];
$group_last=$group_start;
foreach ($mainArray as $value) {
if($group_last+1 == $value){
//continuous series
$group_last=$value;
}
else{
//interrupted series
$groups[]=[$group_start,$group_last];
$group_start=$value;
$group_last=$group_start;
}
}
$groups[]=[$group_start,$group_last];
array_shift($groups);
foreach ($groups as $group_key => $group){
$groups[$group_key] = range($group[0],$group[1]);
}
return $groups;
}
Answer:
Can you try the below code
$seriesArray = array(1, 2, 3, 5, 7, 8, 11, 12, 15);
sort($seriesArray);
$result = array();
$indx = 0;
foreach($seriesArray as $key => $val){
$tmp = $seriesArray[$key];
$next = (isset($seriesArray[$key+1]))? $seriesArray[$key+1] : '';
if($next != ''){
if(!isset($result[$indx])) $result[$indx] = array();
if(($tmp+1) == $next ){
$result[$indx][] = $tmp;
}else{
$result[$indx][] = $tmp;
$indx++;
}
}else{
$result[$indx][] = $tmp;
}
}
foreach($result as $key => $val){
echo "Series ".($key+1)." : ".implode(",",$result[$key])."<br>";
}
print_r($result);