Подтвердить что ты не робот

Настройка внутреннего указателя массива без итерации в PHP

Можно ли установить внутренний указатель внутреннего массива без предварительной итерации через массив. В качестве примера возьмем следующий фиктивный код:

$array = range(1, 100);

// Represents the array key
$pointer = 66;

set_array_pointer($pointer, $array);

$nextValue = next($array); // Should return 68
4b9b3361

Ответ 1

Решение LibertyPaul, предоставляемое с помощью ArrayIterator:: seek, похоже, является единственным способом заставить php установить указатель на позицию в массиве без инициализация цикла в пользовательской области. php будет внутренне прокручивать массив, чтобы установить указатель, хотя, как вы можете читать из php source в ArrayIterator:: seek():

/* {{{ proto void ArrayIterator::seek(int $position)
   Seek to position. */
SPL_METHOD(Array, seek)
{
    zend_long opos, position;
    zval *object = getThis();
    spl_array_object *intern = Z_SPLARRAY_P(object);
    HashTable *aht = spl_array_get_hash_table(intern);
    int result;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &position) == FAILURE) {
        return;
    }

    if (!aht) {
        php_error_docref(NULL, E_NOTICE, "Array was modified outside object and is no longer an array");
        return;
    }

    opos = position;

    if (position >= 0) { /* negative values are not supported */
        spl_array_rewind(intern);
        result = SUCCESS;

        while (position-- > 0 && (result = spl_array_next(intern)) == SUCCESS);

        if (result == SUCCESS && zend_hash_has_more_elements_ex(aht, spl_array_get_pos_ptr(aht, intern)) == SUCCESS) {
            return; /* ok */
        }
    }
    zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Seek position %pd is out of range", opos);
} /* }}} */

Итак, похоже, что невозможно установить указатель на определенную позицию без цикла через массив

Ответ 2

Вы можете сделать это с помощью ArrayObject и ArrayIterator:

$array = range(1, 100);
$pointer = 66;

$arrayobject = new ArrayObject($array);
$iterator = $arrayobject->getIterator();
$iterator->seek($pointer);     //set position
$iterator->next();             // move iterator
$nextValue = $iterator->current();

Ответ 3

вы можете определить свою собственную функцию, используя следующие() и reset(), чтобы использовать указатель и использовать, как показано ниже код

<?php
function findnext (&$array,$key) { 
   reset ($array); 
   while (key($array) !== $key) { 
     if (next($array) === false) throw new Exception('can not find key'); 
   } 
} 

$array = range(1, 100);
$pointer = 66;

findnext($array,$pointer); 
echo next($array); //this will give 68
?>

Ответ 4

Вам не нужно устанавливать фактический pointer для массива. php уже поддерживает указатели внутреннего массива, которые видят следующий метод():

$transport = array('foot', 'bike', 'car', 'plane');
$mode = current($transport); // $mode = 'foot';
$mode = next($transport);    // $mode = 'bike';
$mode = next($transport);    // $mode = 'car';
$mode = prev($transport);    // $mode = 'bike';
$mode = end($transport);     // $mode = 'plane';