PHP: Затем Доступное Значение в Массиве, начиная с неиндексируемого значения

Я озадачивался по этой проблеме PHP приблизительно в течение дня теперь. В основном у нас есть массив часов, отформатированных в 24-часовом формате и произвольном значении ($hour) (также 24-часовое). Проблема, мы должны взять $hour, и получите следующее доступное значение в массиве, начиная со значения, которое сразу продолжается $hour.

Массив мог бы посмотреть что-то как:

$goodHours = array('8,9,10,11,12,19,20,21).

Затем значение часа могло бы быть:

$hour = 14;

Так, нам нужен некоторый способ знать, что 19 следующее наилучшее время. Кроме того, мы, возможно, также должны были бы получить второе, третье, или четвертый (и т.д.) доступное значение.

Проблема, кажется, что, потому что 14 не значение в массиве, нет индекса для ссылки, который позволил бы нам увеличить к следующему значению.

Для создания вещей более простыми я взял $goodHours и повторенный значения несколько раз именно так я не должен иметь дело с возвращением к запуску (возможно, не лучший способ сделать это, но быстрое исправление).

У меня есть чувство, что это - что-то простое, которое я пропускаю, но я был бы так благодарен, если кто-либо мог бы пролить некоторый свет.

Erik

5
задан Gumbo 26 March 2010 в 18:19
поделиться

4 ответа

Вы можете использовать цикл 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 }}
    • выйти из первого цикла, когда он найден
  • Если соответствующий элемент был найден,
    • цикл по массиву до его конца,
    • или вы нашли столько предметов, сколько искали.
4
ответ дан 14 December 2019 в 04:34
поделиться

Попробуйте эту функцию:

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
0
ответ дан 14 December 2019 в 04:34
поделиться

Вы также можете использовать 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
3
ответ дан 14 December 2019 в 04:34
поделиться

Вот ответ, аналогичный остальным, включая необязательный параметр «смещения», с помощью которого ваш 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
0
ответ дан 14 December 2019 в 04:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: