За последние 24 часа нас посетили 20273 программиста и 1715 роботов. Сейчас ищут 1352 программиста ...

как из массива данных вывести интервалы

Тема в разделе "Сделайте за меня", создана пользователем jerkyboy, 30 янв 2025.

  1. jerkyboy

    jerkyboy Активный пользователь

    С нами с:
    4 дек 2020
    Сообщения:
    5
    Симпатии:
    0
    здравствуйте. подскажите, если есть массив чисел и нужно вывести интервалы этих чисел, то вроде ясно, а если в массиве данных числа сопровождаются буквами и символами, то как быть?
    например, в массиве А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):
    1. <?
    2. function array_data_interval($main_ar=array(), $divider='-') {
    3.     sort($main_ar);
    4.     $data=array();
    5.     $begin=$end=0;
    6.     for ($i=0; $i<count($main_ar); $i++) {
    7.         if ($begin==0) {
    8.             $begin=$end=$main_ar[$i];
    9.         }
    10.         if (isset($main_ar[($i+1)])) {
    11.             if ($main_ar[($i+1)]==($end+1)) {
    12.                 $end++;
    13.             }
    14.             else {
    15.                 if ($begin==$end) {
    16.                     $data[]=$begin;
    17.                 }
    18.                 else {
    19.                     $data[]=$begin.$divider.$end;
    20.                 }
    21.                 $begin=$end=0;
    22.             }
    23.         }
    24.     }
    25.     if (count($main_ar)) {
    26.         if ($begin==$end) {
    27.             $data[]=$begin;
    28.         }
    29.         else {
    30.             $data[]=$begin.$divider.$end;
    31.         }
    32.     }
    33.     return $data;
    34. }
     
  2. Дато

    Дато Активный пользователь

    С нами с:
    11 ноя 2021
    Сообщения:
    48
    Симпатии:
    0
    PHP:
    1. function extractPrefix($s) {
    2.     preg_match('/^\D+/', $s, $matches);
    3.     return $matches[0] ?? '';
    4. }
    5.  
    6. function extractNumber($s) {
    7.     preg_match('/\d+/', $s, $matches);
    8.     return (int)($matches[0] ?? 0);
    9. }
    10.  
    11. function groupAndFormatIntervals($data) {
    12.     usort($data, function($a, $b) {
    13.         $prefixA = extractPrefix($a);
    14.         $prefixB = extractPrefix($b);
    15.         if ($prefixA === $prefixB) {
    16.             return extractNumber($a) - extractNumber($b);
    17.         }
    18.         return strcmp($prefixA, $prefixB);
    19.     });
    20.  
    21.     $result = [];
    22.     $currentGroup = [];
    23.     $currentPrefix = '';
    24.  
    25.     foreach ($data as $item) {
    26.         $prefix = extractPrefix($item);
    27.         $number = extractNumber($item);
    28.  
    29.         if ($prefix !== $currentPrefix) {
    30.             if (!empty($currentGroup)) {
    31.                 $result[] = formatInterval($currentGroup, $currentPrefix);
    32.             }
    33.          
    34.             $currentGroup = [$number];
    35.             $currentPrefix = $prefix;
    36.         } else {
    37.            
    38.             $currentGroup[] = $number;
    39.         }
    40.     }
    41.  
    42.     if (!empty($currentGroup)) {
    43.         $result[] = formatInterval($currentGroup, $currentPrefix);
    44.     }
    45.  
    46.     return $result;
    47. }
    48.  
    49. function formatInterval($numbers, $prefix) {
    50.     $intervals = [];
    51.     $start = $numbers[0];
    52.     $prev = $start;
    53.  
    54.     for ($i = 1; $i < count($numbers); $i++) {
    55.         if ($numbers[$i] != $prev + 1) {
    56.             if ($start == $prev) {
    57.                 $intervals[] = "{$prefix}{$start}";
    58.             } else {
    59.                 $intervals[] = "{$prefix}{$start}-{$prefix}{$prev}";
    60.             }
    61.             $start = $numbers[$i];
    62.         }
    63.         $prev = $numbers[$i];
    64.     }
    65.  
    66.     if ($start == $prev) {
    67.         $intervals[] = "{$prefix}{$start}";
    68.     } else {
    69.         $intervals[] = "{$prefix}{$start}-{$prefix}{$prev}";
    70.     }
    71.  
    72.     return implode(', ', $intervals);
    73. }
    74.  
    75. // Пример входных данных
    76. $data = ["А1", "А3", "А4", "А5", "В23", "В24", "В25", "В26", "Ж32", "Ж33", "Ж34", "Z_1", "Z_2", "Z_3", "W 202", "W 203", "W 204"];
    77.  
    78. // Получаем интервалы
    79. $intervals = groupAndFormatIntervals($data);
    80.  
    81. // Выводим результат
    82. foreach ($intervals as $interval) {
    83.     echo $interval . "\n";
    84. }
     
  3. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    457
    Симпатии:
    92
    Адрес:
    Бавария, Германия
    Добрый день!
    так:
    PHP:
    1. function getIntervals($inData){
    2.  
    3.     foreach($inData as $item){
    4.         preg_match("/^\D+/",$item, $out);
    5.         $preGrups[$out[0]][] = $item;
    6.     }
    7.  
    8.     $intervals = [];
    9.     foreach($preGrups as $preff => $preGrup)
    10.     {
    11.         $digs = [];
    12.         foreach($preGrup as $val){
    13.             preg_match("/\d+$/",$val,$out);
    14.             $digs[] = intval($out[0]);
    15.         }
    16.         sort($digs);
    17.         //---------------------------------
    18.         $interval = "";
    19.         foreach($digs as $i => $dig)
    20.         {
    21.             $val = $preff.$dig;
    22.             if($i == 0)
    23.                 $interval = $val;
    24.             else
    25.             {
    26.                 if(($dig - $digs[$i-1]) > 1)
    27.                 {
    28.                     $predVal = $preff.$digs[$i-1];
    29.  
    30.                     if($interval != $predVal AND $i>1)
    31.                         $interval .= " - $predVal";
    32.                     $intervals[] = $interval;
    33.                     $interval = $val;
    34.                 }
    35.             }
    36.         }
    37.         if($interval != $val)
    38.             $interval .= " - $val";
    39.         $intervals[] = $interval;
    40.     }
    41.     return $intervals;
    42. }
    Тест:
    PHP:
    1. echo "<pre>";
    2. $data = ["А1", "А3", "А4", "А5", "В23", "В24", "В25", "В26", "Ж32", "Ж33", "Ж34", "Z_1", "Z_2", "Z_3",
    3. "W 202", "W 203", "W 204"];
    4.  
    5. $intervals = getIntervals($data);
    6. print_r($intervals);
    7. /*
    8. array
    9. (
    10.     [0] => А1
    11.     [1] => А3 - А5
    12.     [2] => В23 - В26
    13.     [3] => Ж32 - Ж34
    14.     [4] => Z_1 - Z_3
    15.     [5] => W 202 - W 204
    16. )
    17. */
    18.  
    19. $data = ["А1", "А3", "А4", "А5", "А6", "А100", "А8", "А9",  "В23", "В24", "В25", "В26", "Ж34", "Ж32",
    20. "Ж33",  "Z_1", "Z_2", "Z_3",
    21. "W 202", "W 203", "W 204"];
    22.  
    23. $intervals = getIntervals($data);
    24. print_r($intervals);
    25.  
    26. /*
    27. Array
    28. (
    29.     [0] => А1
    30.     [1] => А3 - А6
    31.     [2] => А8 - А9
    32.     [3] => А100
    33.     [4] => В23 - В26
    34.     [5] => Ж32 - Ж34
    35.     [6] => Z_1 - Z_3
    36.     [7] => W 202 - W 204
    37. )
    38. */
    39.  
    40. $data = ["А7", "А8", "А9","А4", "А1", "А3", "А5", "В24","В25", "В23", "В26", "Ж34", "Ж32", "Ж33",
    41. "Z_2", "Z_3","Z_1", "W 203", "W 202",  "W 204"];
    42.  
    43. $intervals = getIntervals($data);
    44. print_r($intervals);
    45.  
    46. /*
    47. Array
    48. (
    49.     [0] => А1
    50.     [1] => А3 - А5
    51.     [2] => А7 - А9
    52.     [3] => В23 - В26
    53.     [4] => Ж32 - Ж34
    54.     [5] => Z_1 - Z_3
    55.     [6] => W 202 - W 204
    56. )
    57. */
    58.  
    59. $data = ["А1", "А3", "А4", "А5", "В23", "В24", "В25", "В26", "Ж32", "Ж33", "Ж34", "Z_1", "Z_2", "Z_3",
    60. "W 202", "W 203", "W 204"];
    61. shuffle($data);
    62. print_r($data);
    63. /*
    64. $data Array
    65. (
    66.     [0] => Ж33
    67.     [1] => В25
    68.     [2] => А4
    69.     [3] => В26
    70.     [4] => Z_3
    71.     [5] => А3
    72.     [6] => А1
    73.     [7] => В23
    74.     [8] => W 203
    75.     [9] => W 202
    76.     [10] => Z_2
    77.     [11] => Ж32
    78.     [12] => W 204
    79.     [13] => А5
    80.     [14] => Z_1
    81.     [15] => Ж34
    82.     [16] => В24
    83. )
    84. */
    85. natsort($data);
    86. $intervals = getIntervals($data);
    87. print_r($intervals);
    88. /*
    89. Array
    90. (
    91.     [0] => W 202 - W 204
    92.     [1] => Z_1 - Z_3
    93.     [2] => А1
    94.     [3] => А3 - А5
    95.     [4] => В23 - В26
    96.     [5] => Ж32 - Ж34
    97. )
    98. */
    Удачи!
     
    #3 Vladimir Kheifets, 7 фев 2025
    Последнее редактирование: 7 фев 2025
    jerkyboy нравится это.
  4. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    457
    Симпатии:
    92
    Адрес:
    Бавария, Германия
    Дополнение
    function getIntervals, так проще и лучше
    PHP:
    1. function getIntervals($inData){
    2.     foreach($inData as $item){
    3.         preg_match("/^(\D+)(\d+)$/", $item, $out);
    4.         $preGrups[$out[1]][] = $out[2];
    5.     }
    6.     $intervals = [];
    7.     foreach($preGrups as $preff => $preGrup){
    8.         sort($preGrup);
    9.         //---------------------------------
    10.         $interval = "";
    11.         foreach($preGrup as $i => $dig)
    12.         {
    13.             $val = $preff.$dig;
    14.             if($i == 0)
    15.                 $interval = $val;
    16.             else
    17.             {
    18.                 if(($dig - $preGrup[$i-1]) > 1)
    19.                 {
    20.                     $predVal = $preff.$preGrup[$i-1];
    21.  
    22.                     if($interval != $predVal AND $i>1)
    23.                         $interval .= " - $predVal";
    24.                     $intervals[] = $interval;
    25.                     $interval = $val;
    26.                 }
    27.             }
    28.         }
    29.         if($interval != $val)
    30.             $interval .= " - $val";
    31.         $intervals[] = $interval;
    32.     }
    33.     return $intervals;
    34. }
     
    jerkyboy нравится это.
  5. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    457
    Симпатии:
    92
    Адрес:
    Бавария, Германия
    Дополнение
    function getIntervals на ECMAScript®
    Код (Javascript):
    1. 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"];
    2.  
    3. function getIntervals(inData){
    4.  
    5.     const regex = /^(\D+)(\d+)$/;
    6.     let preGrups = {};
    7.  
    8.     for(let item of data){
    9.         let out = regex.exec(item);
    10.         if(!preGrups[out[1]])
    11.             preGrups[out[1]]=[];
    12.         preGrups[out[1]].push(out[2]);
    13.     }
    14.  
    15.     let intervals = [];
    16.  
    17.     for( let preff in preGrups)
    18.     {
    19.         let preGrup = preGrups[preff];
    20.         preGrup.sort();
    21.  
    22.         for (const [i, dig] of Object.entries(preGrup))
    23.         {
    24.             var val = preff + dig;
    25.             if(i == 0)
    26.                 var interval = val;
    27.             else
    28.             {
    29.                 if((dig - preGrup[i-1]) > 1)
    30.                 {
    31.                     predVal = preff+preGrup[i-1];
    32.  
    33.                     if(interval != predVal && i>1)
    34.                         $interval += ` - ${predVal}`;
    35.                     intervals.push(interval);
    36.                     interval = val;
    37.                 }
    38.             }
    39.         }
    40.         if(interval != val)
    41.             interval += ` - ${val}`;
    42.         intervals.push(interval);
    43.     }
    44.     return intervals;
    45. }
    46.  
    47. console.log( getIntervals(data) );
    48.  
    49. /*
    50. Array(6) [ "А1", "А3 - А5", "В23 - В26", "Ж32 - Ж34", "Z_1 - Z_3", "W 202 - W 204" ]
    51. */
     
    jerkyboy нравится это.