Как найти отсутствующие значения в последовательности с PHP?

Предположим, у вас есть массив «value => timestamp». Значения возрастают со временем, но в любой момент они могут быть сброшены.

Например :

$array = array( 1 => 6000, 2 => 7000, 3 => 8000, 7 => 9000, 8 => 10000, 9 => 11000, 55 => 1000, 56 => 2000, 57 => 3000, 59 => 4000, 60 => 5000, ); 

Я хотел бы получить все недостающие значения из этого массива.

Этот пример вернет:

 array(4,5,6,58) 

Я не хочу, чтобы все значения находились между 9 и 55, потому что 9 является более новым, чем другие более высокие значения.

В реальном состоянии сценарий будет иметь дело с тысячами ценностей, поэтому он должен быть эффективным.

Спасибо за вашу помощь!


UPDATE: начальный массив можно упорядочить по временным меткам, если это проще для алгоритма.


ОБНОВЛЕНИЕ 2: В моем примере значениями являются отметки времени UNIX, поэтому они выглядели бы так: 1285242603, но для удобства чтения я упростил это.

Вот еще одно решение:

 $prev = null; $missing = array(); foreach ($array as $curr => $value) { if (!is_null($prev)) { if ($curr > $prev+1 && $value > $array[$prev]) { $missing = array_merge($missing, range($prev+1, $curr-1)); } } $prev = $curr; } 

Вы можете сделать следующее:

  • Продолжайте сравнивать соседние ключи массива. Если они последовательны, вы ничего не делаете.
  • Если они не последовательны, то вы проверяете их значения, если значение упало с более высокого значения до более низкого значения, это означает, что произошел сбой, поэтому вы ничего не делаете.
  • Если значение не упало, это случай отсутствия ключа (ов). Все числа между двумя клавишами (крайние значения не включены) являются частью результата.

Переведено в коде:

 $array = array( 1 => 6000, 2 => 7000, 3 => 8000, 7 => 9000, 8 => 10000, 9 => 11000,55 => 1000, 56 => 2000, 57 => 3000, 59 => 4000, 60 => 5000,); $keys = array_keys($array); for($i=0;$i<count($array)-1;$i++) { if($array[$keys[$i]] < $array[$keys[$i+1]] && ($keys[$i+1]-$keys[$i] != 1) ) { print(implode(' ',range($keys[$i]+1,$keys[$i+1]-1))); print "\n"; } } 

Рабочая ссылка

Это дает желаемый array(4,5,6,58) результатов array(4,5,6,58) :

 $previous_value = NULL; $temp_store = array(); $missing = array(); $keys = array_keys($array); for($i = min($keys); $i <= max($keys); $i++) { if(!array_key_exists($i, $array)) { $temp_store[] = $i; } else { if($previous_value < $array[$i]) { $missing = array_merge($missing, $temp_store); } $temp_store = array(); $previous_value = $array[$i]; } } var_dump($missing); 

Или просто используйте очень умное решение Gumbo 😉