здравствуйте. подскажите, если есть массив чисел и нужно вывести интервалы этих чисел, то вроде ясно, а если в массиве данных числа сопровождаются буквами и символами, то как быть? например, в массиве А1,А3,А4,А5,В23,В24,В25,В26, Ж32, Ж33, Ж34, Z_1, Z_2, Z_3, W 202, W 203, W 204 и тп. нужно на выходе получить список интервалов А1 А3-А5 В23-В26 Ж32-Ж34 Z_1-Z_3 W 202-W 204 Спойлер: для чисел такой код использовал Код (Text): <? function array_data_interval($main_ar=array(), $divider='-') { sort($main_ar); $data=array(); $begin=$end=0; for ($i=0; $i<count($main_ar); $i++) { if ($begin==0) { $begin=$end=$main_ar[$i]; } if (isset($main_ar[($i+1)])) { if ($main_ar[($i+1)]==($end+1)) { $end++; } else { if ($begin==$end) { $data[]=$begin; } else { $data[]=$begin.$divider.$end; } $begin=$end=0; } } } if (count($main_ar)) { if ($begin==$end) { $data[]=$begin; } else { $data[]=$begin.$divider.$end; } } return $data; }
PHP: function extractPrefix($s) { preg_match('/^\D+/', $s, $matches); return $matches[0] ?? ''; } function extractNumber($s) { preg_match('/\d+/', $s, $matches); return (int)($matches[0] ?? 0); } function groupAndFormatIntervals($data) { usort($data, function($a, $b) { $prefixA = extractPrefix($a); $prefixB = extractPrefix($b); if ($prefixA === $prefixB) { return extractNumber($a) - extractNumber($b); } return strcmp($prefixA, $prefixB); }); $result = []; $currentGroup = []; $currentPrefix = ''; foreach ($data as $item) { $prefix = extractPrefix($item); $number = extractNumber($item); if ($prefix !== $currentPrefix) { if (!empty($currentGroup)) { $result[] = formatInterval($currentGroup, $currentPrefix); } $currentGroup = [$number]; $currentPrefix = $prefix; } else { $currentGroup[] = $number; } } if (!empty($currentGroup)) { $result[] = formatInterval($currentGroup, $currentPrefix); } return $result; } function formatInterval($numbers, $prefix) { $intervals = []; $start = $numbers[0]; $prev = $start; for ($i = 1; $i < count($numbers); $i++) { if ($numbers[$i] != $prev + 1) { if ($start == $prev) { $intervals[] = "{$prefix}{$start}"; } else { $intervals[] = "{$prefix}{$start}-{$prefix}{$prev}"; } $start = $numbers[$i]; } $prev = $numbers[$i]; } if ($start == $prev) { $intervals[] = "{$prefix}{$start}"; } else { $intervals[] = "{$prefix}{$start}-{$prefix}{$prev}"; } return implode(', ', $intervals); } // Пример входных данных $data = ["А1", "А3", "А4", "А5", "В23", "В24", "В25", "В26", "Ж32", "Ж33", "Ж34", "Z_1", "Z_2", "Z_3", "W 202", "W 203", "W 204"]; // Получаем интервалы $intervals = groupAndFormatIntervals($data); // Выводим результат foreach ($intervals as $interval) { echo $interval . "\n"; }
Добрый день! так: PHP: function getIntervals($inData){ foreach($inData as $item){ preg_match("/^\D+/",$item, $out); $preGrups[$out[0]][] = $item; } $intervals = []; foreach($preGrups as $preff => $preGrup) { $digs = []; foreach($preGrup as $val){ preg_match("/\d+$/",$val,$out); $digs[] = intval($out[0]); } sort($digs); //--------------------------------- $interval = ""; foreach($digs as $i => $dig) { $val = $preff.$dig; if($i == 0) $interval = $val; else { if(($dig - $digs[$i-1]) > 1) { $predVal = $preff.$digs[$i-1]; if($interval != $predVal AND $i>1) $interval .= " - $predVal"; $intervals[] = $interval; $interval = $val; } } } if($interval != $val) $interval .= " - $val"; $intervals[] = $interval; } return $intervals; } Тест: PHP: echo "<pre>"; $data = ["А1", "А3", "А4", "А5", "В23", "В24", "В25", "В26", "Ж32", "Ж33", "Ж34", "Z_1", "Z_2", "Z_3", "W 202", "W 203", "W 204"]; $intervals = getIntervals($data); print_r($intervals); /* array ( [0] => А1 [1] => А3 - А5 [2] => В23 - В26 [3] => Ж32 - Ж34 [4] => Z_1 - Z_3 [5] => W 202 - W 204 ) */ $data = ["А1", "А3", "А4", "А5", "А6", "А100", "А8", "А9", "В23", "В24", "В25", "В26", "Ж34", "Ж32", "Ж33", "Z_1", "Z_2", "Z_3", "W 202", "W 203", "W 204"]; $intervals = getIntervals($data); print_r($intervals); /* Array ( [0] => А1 [1] => А3 - А6 [2] => А8 - А9 [3] => А100 [4] => В23 - В26 [5] => Ж32 - Ж34 [6] => Z_1 - Z_3 [7] => W 202 - W 204 ) */ $data = ["А7", "А8", "А9","А4", "А1", "А3", "А5", "В24","В25", "В23", "В26", "Ж34", "Ж32", "Ж33", "Z_2", "Z_3","Z_1", "W 203", "W 202", "W 204"]; $intervals = getIntervals($data); print_r($intervals); /* Array ( [0] => А1 [1] => А3 - А5 [2] => А7 - А9 [3] => В23 - В26 [4] => Ж32 - Ж34 [5] => Z_1 - Z_3 [6] => W 202 - W 204 ) */ $data = ["А1", "А3", "А4", "А5", "В23", "В24", "В25", "В26", "Ж32", "Ж33", "Ж34", "Z_1", "Z_2", "Z_3", "W 202", "W 203", "W 204"]; shuffle($data); print_r($data); /* $data Array ( [0] => Ж33 [1] => В25 [2] => А4 [3] => В26 [4] => Z_3 [5] => А3 [6] => А1 [7] => В23 [8] => W 203 [9] => W 202 [10] => Z_2 [11] => Ж32 [12] => W 204 [13] => А5 [14] => Z_1 [15] => Ж34 [16] => В24 ) */ natsort($data); $intervals = getIntervals($data); print_r($intervals); /* Array ( [0] => W 202 - W 204 [1] => Z_1 - Z_3 [2] => А1 [3] => А3 - А5 [4] => В23 - В26 [5] => Ж32 - Ж34 ) */ Удачи!
Дополнение function getIntervals, так проще и лучше PHP: function getIntervals($inData){ foreach($inData as $item){ preg_match("/^(\D+)(\d+)$/", $item, $out); $preGrups[$out[1]][] = $out[2]; } $intervals = []; foreach($preGrups as $preff => $preGrup){ sort($preGrup); //--------------------------------- $interval = ""; foreach($preGrup as $i => $dig) { $val = $preff.$dig; if($i == 0) $interval = $val; else { if(($dig - $preGrup[$i-1]) > 1) { $predVal = $preff.$preGrup[$i-1]; if($interval != $predVal AND $i>1) $interval .= " - $predVal"; $intervals[] = $interval; $interval = $val; } } } if($interval != $val) $interval .= " - $val"; $intervals[] = $interval; } return $intervals; }
Дополнение function getIntervals на ECMAScript® Код (Javascript): const data = ["А5","А1", "А4", "А3", "В23", "В24", "В25", "В26", "Ж32", "Ж33", "Ж34", "Z_1", "Z_2", "Z_3","W 202", "W 203", "W 204"]; function getIntervals(inData){ const regex = /^(\D+)(\d+)$/; let preGrups = {}; for(let item of data){ let out = regex.exec(item); if(!preGrups[out[1]]) preGrups[out[1]]=[]; preGrups[out[1]].push(out[2]); } let intervals = []; for( let preff in preGrups) { let preGrup = preGrups[preff]; preGrup.sort(); for (const [i, dig] of Object.entries(preGrup)) { var val = preff + dig; if(i == 0) var interval = val; else { if((dig - preGrup[i-1]) > 1) { predVal = preff+preGrup[i-1]; if(interval != predVal && i>1) $interval += ` - ${predVal}`; intervals.push(interval); interval = val; } } } if(interval != val) interval += ` - ${val}`; intervals.push(interval); } return intervals; } console.log( getIntervals(data) ); /* Array(6) [ "А1", "А3 - А5", "В23 - В26", "Ж32 - Ж34", "Z_1 - Z_3", "W 202 - W 204" ] */