@gibigate

Как разделить массив по заданному критерию?

Здравствуйте,

Появилась задачка, ищу изящное решение с минимумом кода.
  • Вопрос задан
  • 152 просмотра
Пригласить эксперта
Ответы на вопрос 4
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
function intervals($arr) {
  $start = -1;
  $end = -1;
  $result = [];
  foreach ($arr as $val) {
    if ($start === -1) {
      $start = $val;
      $end = $val;
    } elseif ($val === $end + 1) {
      $end = $val;
    } else {
      $result[] = ['start' => $start, 'end' => $end];
      $start = $val;
      $end = $val;
    }
  }
  if ($start !== -1) {
    $result[] = ['start' => $start, 'end' => $end];
  }
  return $result;
}

print_r(intervals([0,1,2,3,6,7,8,9,12,13,14,15]));

// Array (
//     [0] => Array (
//             [start] => 0
//             [end] => 3
//     )
//     [1] => Array (
//             [start] => 6
//             [end] => 9
//      )
//     [2] => Array (
//             [start] => 12
//             [end] => 15
//      )
// )
Ответ написан
Fragster
@Fragster
помогло? отметь решением!
мой вариант:

function convert($data) {
        $result = [];
        $needle = NIL;

        foreach ($data as $item) {
            if ($item - 1 !== $needle) {
                if ($needle !== NIL) {
                    $obj['end'] = $needle;
                    $result[] = $obj;
                }
                $obj = ['start' => $item];
            }
            $needle = $item;
        }
        $obj['end'] = $item;
        $result[] = $obj;

        return $result;
    }

    print_r(convert([0, 1, 2, 3, 4, 5]));
    print_r(convert([0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15]));
    print_r(convert([94, 95]));
    print_r(convert([0, 1, 94, 95]));
Ответ написан
Комментировать
@Nc_Soft
<?php
$dataset = [
    [0, 1, 2, 3, 4, 5],
    [0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15],
    [94, 95],
    [0, 1, 94, 95],
];

function arrange($array)
{
    $groups = [];
    $group = null;
    foreach ($array as $index => $current) {
        if ($group === null) {
            $group = [
                'start' => $current,
                'end' => $current
            ];
            continue;
        }
        $group['end'] = $current;
        $next = $index + 1;
        if (array_key_exists($next, $array)) {
            if ($array[$next] - $current !== 1) {
                array_push($groups, $group);
                $group = null;
            }
        }
    }
    if ($group !== null) {
        array_push($groups, $group);
    }
    return $groups;
}

foreach ($dataset as $array) {
    $arrange = arrange($array);
    print_r($arrange);
}
Ответ написан
Комментировать
<?php

$numbers1 = [-5, 10, 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15];
$numbers2 = [10, 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15];

function intervals(array $numbers): array
{
    $numbers = array_unique($numbers);
    sort($numbers);

    $length = count($numbers);

    $intervals = [];

    $start = null;
    $end   = null;

    for ($i = 0; $i < $length; $i++) {
        $currentItem = $numbers[$i];
        $nextItem    = $numbers[$i + 1] ?? null;

        if ($currentItem + 1 === $nextItem) {
            if ($start === null) {
                $start = $currentItem;
            }

            $end = $nextItem;
            continue;
        }

        if ($start === null || $end === null) {
            continue;
        }

        $intervals[] = [
            'start' => $start,
            'end'   => $end,
        ];

        $start = $nextItem;
    }

    return $intervals;
}

print_r(intervals($numbers1));
print_r(intervals($numbers2));


P.S. gibigate проверь предыдущие ответы на массиве, у которого первая цифра не имеет пары
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽
26 апр. 2024, в 09:18
500 руб./в час
26 апр. 2024, в 06:46
1500 руб./в час
26 апр. 2024, в 05:31
1000 руб./за проект