Intereting Posts
Таймер обратного отсчета Javascript, который останавливается, когда окно не находится в фокусе WordPress Admin: при размещении пользовательского типа сообщения в качестве подменю родительского меню ссылка родительского меню переопределяется CPT Пользовательская команда IMAP в php Очень странное поведение Drupal 7 404 Извлечение значения из текстового поля в форме (представлении) в контроллер в codeigniter php при выборе selectbox Как эффективно подключаться к mysql в php без повторного подключения к каждому запросу Работа с __get () по ссылке Отключить PHP в каталоге (включая все подкаталоги) с помощью .htaccess Ошибка при установке драйвера MongoDb PHP с XAMPP на Max OS Lion Изображения PHP переименовывают двойные цифры Перенаправить на более старую страницу в php? Необходимо объединить несколько PDF-файлов в один PDF-файл с разделами «Содержание» Загрузить FOLDER Как создать модель Laravel без Красноречивого? Weird формат массива $ _FILES при наличии нескольких полей

Объединение перекрывающихся диапазонов в массивах PHP?

У меня есть массив в следующем формате:

array( 0 => array(1, 5), 1 => array(4, 8), 2 => array(19, 24), 3 => array(6, 9), 4 => array(11, 17), ); 

Где каждый элемент представляет собой диапазон X-to-Y. Я хотел бы объединить перекрывающиеся диапазоны в массиве, чтобы получить что-то большее:

 array( 0 => array(1, 9), // 1-5, 4-8 and 6-9 are overlapping, so they are merged 1 => array(11, 17), 2 => array(19, 24), ); 

Какой был бы лучший способ сделать это?

Related of "Объединение перекрывающихся диапазонов в массивах PHP?"

Untested, но идея здесь состоит в том, чтобы сначала отсортировать данные по первому элементу, а затем объединить последующие элементы с предыдущим как можно дольше.

 usort($data, function($a, $b) { return $a[0] - $b[0]; }); $n = 0; $len = count($data); for ($i = 1; $i < $len; ++$i) { if ($data[$i][0] > $data[$n][1] + 1) $n = $i; else { if ($data[$n][1] < $data[$i][1]) $data[$n][1] = $data[$i][1]; unset($data[$i]); } } $data = array_values($data); не usort($data, function($a, $b) { return $a[0] - $b[0]; }); $n = 0; $len = count($data); for ($i = 1; $i < $len; ++$i) { if ($data[$i][0] > $data[$n][1] + 1) $n = $i; else { if ($data[$n][1] < $data[$i][1]) $data[$n][1] = $data[$i][1]; unset($data[$i]); } } $data = array_values($data); 
 $input = array( 0 => array(1, 5), 1 => array(4, 8), 2 => array(19, 24), 3 => array(6, 9), 4 => array(11, 17), ); $tmpArray = array(); foreach($input as $rangeSet) { $tmpArray = array_unique(array_merge($tmpArray,range($rangeSet[0],$rangeSet[1]))); } sort($tmpArray); $oldElement = array_shift($tmpArray); $newArray = array(array($oldElement)); $ni = 0; foreach($tmpArray as $newElement) { if ($newElement > $oldElement+1) { $newArray[$ni++][] = $oldElement; $newArray[$ni][] = $newElement; } $oldElement = $newElement; } $newArray[$ni++][] = $oldElement; var_dump($newArray); 

Хорошо, разработал это, так что у него могут быть причуды. Протестировал его с данными, представленными ниже, и, казалось, работал нормально. Возможно, это не лучший способ сделать это, но это один из способов, и он работает. Вопросы дайте мне знать.

 function combineRange($array) { if (is_array($array)) { // Sort the array for numerical order sort($array); // Set Defaults $prev = array(); $prev_key = null; foreach ($array as $key => $item) { // First time around setup default data if (empty($prev)) { $prev = $item; $prev_key = $key; continue; } if ($item[0] >= $prev[0] && $item[0] <= $prev[1]) { // Incase the last number was less than do not update if ($array[$prev_key][1] < $item[1]) $array[$prev_key][1] = $item[1]; unset($array[$key]); }else { $prev_key = $key; } $prev = $item; } } return $array; } $array = array( 5 => array(13, 16), 0 => array(1, 5), 1 => array(4, 8), 2 => array(19, 24), 3 => array(6, 9), 4 => array(11, 17), 6 => array(21, 30), ); var_dump(combineRange($array)); с function combineRange($array) { if (is_array($array)) { // Sort the array for numerical order sort($array); // Set Defaults $prev = array(); $prev_key = null; foreach ($array as $key => $item) { // First time around setup default data if (empty($prev)) { $prev = $item; $prev_key = $key; continue; } if ($item[0] >= $prev[0] && $item[0] <= $prev[1]) { // Incase the last number was less than do not update if ($array[$prev_key][1] < $item[1]) $array[$prev_key][1] = $item[1]; unset($array[$key]); }else { $prev_key = $key; } $prev = $item; } } return $array; } $array = array( 5 => array(13, 16), 0 => array(1, 5), 1 => array(4, 8), 2 => array(19, 24), 3 => array(6, 9), 4 => array(11, 17), 6 => array(21, 30), ); var_dump(combineRange($array)); 

Выходы:

 array(3) { [0]=> array(2) { [0]=> int(1) [1]=> int(9) } [3]=> array(2) { [0]=> int(11) [1]=> int(17) } [5]=> array(2) { [0]=> int(19) [1]=> int(30) } } 

Надеюсь, он работает на тебя!

РЕДАКТИРОВАТЬ

Я вижу, что я был избит на час = \ О, хорошо! Я все еще размещаю, поскольку это другой метод, и я, скорее всего, выбрал бы метод konforce.