如何循环一个数组,当我们到达终点时重新开始?

时间:2013-12-22 16:50:54

标签: php arrays

我有一个我想要传递给函数的url数组,我将使用cron作业每10分钟只传递其中的2个,我将这个数组的最后一个传递的索引存储在一个数据库,问题是我不知道如何传递前2个元素,当最后传递的元素是数组中的最后一个元素时,让我用代码解释:

$sites = array(
    'http://www.example.com/',
    'http://www.example1.com/',
    'http://www.example2.com/',
    'http://www.example3.com/',
    'http://www.example4.com/',
    'http://www.example5.com/'
);

// the number of urls to pass to the function
// Edit: I forgot to say that this number might change later
$sites_to_pass = 2;

// this value is supposed to be stored when we finish processing the urls
$last_passed_index = 2;

// this is the next element's index to slice from
$start_from = $last_passed_index + 1;

// I also want to preserve the keys to keep track of the last passed index
$to_pass = array_slice($sites, $start_from, $sites_to_pass, true);

array_slice()工作正常,但当$last_passed_index4时,我只获取数组中的最后一个元素,当它是5(最后一个索引)时得到一个空数组。

我想要做的是当4获取最后一个元素和第一个元素时,以及它是5时,它是获取数组中前两个元素的最后一个元素的索引。

我对php不太满意,有什么建议我应该做什么而不是创建一个检查索引的函数?

3 个答案:

答案 0 :(得分:1)

半聪明技巧:使用array_merge复制网址列表,以便重复两次。然后从那个加倍的列表中选择。这样你就可以从与开头重叠的一端选择切片。

$start_from = ($last_passed_index + 1) % count($sites_to_pass);
$to_pass    = array_slice(array_merge($sites, $sites), $start_from, $sites_to_pass, true);

添加% count($sites_to_pass)会使$start_from一旦超过数组末尾就重新开始。这让你永远循环。

答案 1 :(得分:1)

一个有趣的解决方案是使用SPL IteratorsInfiniteIterator是要使用的。

在此示例中,您从最后一个数组元素开始并迭代两次:

$sites = array(
    'http://www.example0.com/',
    'http://www.example1.com/',
    'http://www.example2.com/',
    'http://www.example3.com/',
    'http://www.example4.com/',
    'http://www.example5.com/'
);

$result = array();
$infinite = new InfiniteIterator(new ArrayIterator($sites));

// this value is supposed to be stored when we finish processing the urls
$last_passed_index = 5;

// this is the next element's index to slice from
$start_from = $last_passed_index + 1;

foreach (new LimitIterator($infinite, $start_from, 2) as $site) {
    $result[] = $site;
}

var_dump($result);

// output
array(2) {
  [0]=>
  string(24) "http://www.example0.com/"
  [1]=>
  string(24) "http://www.example1.com/"
}

答案 2 :(得分:0)

有点脏,但有点像:

$to_pass = $start_from == 5 ? array($sites[5], $sites[0]) : array_slice($sites, $start_from, $sites_to_pass, true);