从一个特定的键迭代一个PHP数组

goucqfw6  于 2023-04-28  发布在  PHP
关注(0)|答案(7)|浏览(107)

我知道如何在PHP中迭代数组,但我想从特定的键迭代数组。
假设我有一个巨大的数组

$my_array = array(
    ...
    ...
    ["adad"] => "value X",
    ["yy"] => "value Y",
    ["hkghgk"] => "value Z",
    ["pp"] => "value ZZ",
    ...
    ...
)

我知道从哪里开始迭代(“yy”)。现在我只想从这个键迭代到另一个键。
我知道我不想这么做

$start_key = "yy";
foreach ($my_array as $key => $v)
{
    if ($key == $start_key)
        ...
}

我一直在寻找迭代器,但我不认为这是我需要的。

tmb3ates

tmb3ates1#

尝试组合array_search、array_key和LimitIterator。使用LimitIterator页面中的示例和一些额外的位:

$fruitsArray = array(
    'a' => 'apple',
    'b' => 'banana',
    'c' => 'cherry',
    'd' => 'damson',
    'e' => 'elderberry'
);

$startkey = array_search('d', array_keys($fruitsArray));

$fruits = new ArrayIterator($fruitsArray);

foreach (new LimitIterator($fruits, $startkey) as $fruit) {
    var_dump($fruit);
}

从位置“d”开始,输出:

string(6) "damson" string(10) "elderberry"

这种方法有一个限制,它不会在数组中循环,直到再次返回开始位置。它只会迭代到数组的末尾,然后停止。你必须运行另一个foreach来完成数组的第一部分,但这可以通过我们已有的代码轻松完成。

foreach (new LimitIterator($fruits, 0, $startkey-1) as $fruit) {
    var_dump($fruit);
}

这从第一个元素开始,直到我们搜索的元素之前的元素。

bxgwgixi

bxgwgixi2#

foreach总是重置数组的数组指针。你不能按照你想象的方式去做。
你还有几种方法。foreach 的方法只是跳过所有内容,直到找到一次密钥:

$start_key = "yy";
$started = false;
foreach ($my_array as $key => $v)
{
    if ($key == $start_key) {
        $started = true;
    }
    if (!$started) {
        continue;
    }
    // your code
}

你也可以使用数组指针并使用while (list($key, $v) = each($array))方法:

$start_key = "yy";
reset($array); // reset it to be sure to start at the beginning
while (list($key, $v) = each($array) && $key != $start_key); // set array pointer to $start_key
do {
    // your code
} while (list($key, $v) = each($array));

或者,你可以像MarkBaker建议的那样提取你想要迭代的数组。

nr9pn0ug

nr9pn0ug3#

可能类似于:

foreach(array_slice(
    $my_array,
    array_search(
        $start_key,array_keys($my_array)
    ),
    null,
    true) as $key => $v) {}

Demo

1qczuiv0

1qczuiv04#

可以使用array_keysarray_search
就像这样:

$keys = array_keys( $my_array ); // store all of your array indexes in a new array
$position = array_search( "yy" ,$keys ); // search your starting index in the newly created array of indexes
if( $position == false ) exit( "Index doesn't exist" ); // if the starting index doesn't exist the array_search returns false

for( $i = $position; $i < count( $keys ); $i++  ) { // starting from your desired index, this will iterate over the rest of your array
    // do your stuff to $my_array[ $keys[ $i ] ] like:
    echo $my_array[ $keys[ $i ] ];
}
qkf9rpyu

qkf9rpyu5#

试试这样:

$startkey = array_search('yy', array_keys($my_array));
$endkey = array_search('zz', array_keys($my_array));

$my_array2 = array_values($my_array);

for($i = $startkey; $i<=$endkey; $i++)
{
    // Access array like this
    echo $my_array2[$i];
}
wgx48brx

wgx48brx6#

如果this pull request通过了,你就可以很容易地做到这一点:

if (seek($array, 'yy', SEEK_KEY)) {
    while ($data = each($array)) {
        // Do stuff
    }
}
vh0rcniy

vh0rcniy7#

如果你创建一个数组,然后多次使用它,你可以索引数组键,这将比每次迭代所有元素更有效和干净。以这个类为例:

<?php

class IndexedArrayIterator implements Iterator {
    
    protected $data=array();
    protected $keyIndex=array();
    protected $reverseIndex=array();
    protected $position=0;
    protected $startIndex=0;
    protected $endIndex=0;
    
    function __construct($source) {
        $this->data=$source;
        $this->reindex();
    }
    
    function reindex() {
        // Reindexing is expensive, don't do it often
        // If you need to reindex every time you search, you loose the advantage
        // If you add elements, you must reindex
        $this->keyIndex = array_keys($this->data);
        $this->reverseIndex = array_flip($this->keyIndex);
    }
    
    function setStartKey($start) {
        $this->startIndex=$this->reverseIndex[$start];
    }
    
    function setEndKey($end) {
        $this->endIndex=$this->reverseIndex[$end];
    }
    

    /////
    ///      Iterator Interface
    //

    #[\ReturnTypeWillChange]
    public function rewind() {
        $this->position=$this->startIndex;
    }

    #[\ReturnTypeWillChange]
    public function current() {
        if($this->valid()) return $this->data[$this->key()];
        else return NULL;
    }

    #[\ReturnTypeWillChange]
    public function key() {
        if($this->valid()) return $this->keyIndex[$this->position];
        else return NULL;
    }

    #[\ReturnTypeWillChange]
    public function next() {
        ++$this->position;
    }

    #[\ReturnTypeWillChange]
    public function valid() {
        if($this->position > $this->endIndex) return FALSE;
        return isset($this->keyIndex[$this->position]);
    }
    
}

使用示例:

$iterator=new IndexedArrayIterator([
    'one'=>'Item One',
    'two'=>'Item Two',
    'twoandhalf'=>'Item Two And Half',
    'three'=>'Item Three',
    'four'=>'Item Four',
]);

$iterator->setStartKey('two');
$iterator->setEndKey('three');

foreach($iterator as $key=>$value) {
    echo(''.$key.': '.$value."\r\n");
}

工作代码:
https://3v4l.org/EP0fL

相关问题