Я озадачивался по этой проблеме PHP приблизительно в течение дня теперь. В основном у нас есть массив часов, отформатированных в 24-часовом формате и произвольном значении ($hour
) (также 24-часовое). Проблема, мы должны взять $hour
, и получите следующее доступное значение в массиве, начиная со значения, которое сразу продолжается $hour
.
Массив мог бы посмотреть что-то как:
$goodHours = array('8,9,10,11,12,19,20,21).
Затем значение часа могло бы быть:
$hour = 14;
Так, нам нужен некоторый способ знать, что 19 следующее наилучшее время. Кроме того, мы, возможно, также должны были бы получить второе, третье, или четвертый (и т.д.) доступное значение.
Проблема, кажется, что, потому что 14 не значение в массиве, нет индекса для ссылки, который позволил бы нам увеличить к следующему значению.
Для создания вещей более простыми я взял $goodHours
и повторенный значения несколько раз именно так я не должен иметь дело с возвращением к запуску (возможно, не лучший способ сделать это, но быстрое исправление).
У меня есть чувство, что это - что-то простое, которое я пропускаю, но я был бы так благодарен, если кто-либо мог бы пролить некоторый свет.
Erik
Вы можете использовать цикл for для перебора массива, пока не найдете первый, который больше, чем тот вы ищете:
$goodHours = array(8,9,10,11,12,19,20,21);
$hour = 14;
$length = count($goodHours);
for ($i = 0 ; $i < $length ; $i++) {
if ($goodHours[$i] >= $hour) {
echo "$i => {$goodHours[$i]}";
break;
}
}
Дало бы вам:
5 => 19
И, чтобы получить элемент, который вы искали, и некоторые после него, вы можете использовать что-то вроде этого:
$goodHours = array(8,9,10,11,12,19,20,21);
$hour = 14;
$numToFind = 2;
$firstIndex = -1;
$length = count($goodHours);
for ($i = 0 ; $i < $length ; $i++) {
if ($goodHours[$i] >= $hour) {
$firstIndex = $i;
break;
}
}
if ($firstIndex >= 0) {
$nbDisplayed = 0;
for ($i=$firstIndex ; $i<$length && $nbDisplayed<$numToFind ; $i++, $nbDisplayed++) {
echo "$i => {$goodHours[$i]}<br />";
}
}
Что даст вам следующий результат:
5 => 19
6 => 20
По сути, здесь идея состоит в том, чтобы:
> =
тому, что вы ищете
{{1 }} Попробуйте эту функцию:
function nextValueGreaterThan($haystack, $needle, $n=1) {
sort($haystack);
foreach ($haystack as $val) {
if ($val >= $needle) {
$n--;
if ($n <= 0) {
return $val;
}
}
}
}
$goodHours = array(8,9,10,11,12,19,20,21);
echo nextValueGreaterThan($goodHours, 14); // 19
echo nextValueGreaterThan($goodHours, 14, 3); // 21
Вы также можете использовать SPL FilterIterator . Хотя это не самое быстрое решение, оно имеет то преимущество, что вы можете «подготовить» итератор где-нибудь / в любом месте, а затем передать его функции / методу, который не должен знать, как итератор работает внутри, т.е. вы может в следующий раз передать совершенно другой итератор.
class GreaterThanFilterIterator extends FilterIterator {
protected $threshold;
public function __construct($threshold, Iterator $it) {
$this->threshold = $threshold;
parent::__construct($it);
}
public function accept() {
return $this->threshold < parent::current();
}
}
function doSomething($it) {
// no knowledge of the FilterIterator here
foreach($it as $v) {
echo $v, "\n";
}
}
$goodHours = array(8,9,10,11,12,19,20,21);
$it = new GreaterThanFilterIterator(14, new ArrayIterator($goodHours));
doSomething($it);
печатает
19
20
21
Вот ответ, аналогичный остальным, включая необязательный параметр «смещения», с помощью которого ваш n-й элемент проходит мимо фактического первого. .
class GoodHours {
private $hours = array(8,9,10,11,12,19,20,21);
public function getGoodHour($hour, $offset = 0) {
$length = count($this->hours);
for ($i = 0 ; $i < $length && $this->hours[$i] < $hour ; $i++)
; // do nothing
return $this->hours[($i + $offset) % $length];
}
}
// some test values
$good = new GoodHours();
$x = $good->getGoodHour(5); // 8
$x = $good->getGoodHour(5,1); // 9
$x = $good->getGoodHour(5,2); // 10
$x = $good->getGoodHour(10); // 10
$x = $good->getGoodHour(10,1); // 11
$x = $good->getGoodHour(10,2); // 12
$x = $good->getGoodHour(21); // 21
$x = $good->getGoodHour(21,1); // 8
$x = $good->getGoodHour(21,2); // 9
$x = $good->getGoodHour(21); // 8
$x = $good->getGoodHour(22,1); // 9
$x = $good->getGoodHour(22,2); // 10