我有一个foreach,它在数组中的项目之间迭代以构建excel文件。如果数组中的下一个元素与特定条件匹配(在一个键中具有特定值),我想在数组中的每个项目之后放置一个总计行。所以我想使用 next()
来检查该值,但据我所知,对于我在这里阅读的内容,接下来我将指针移动到下一行,答案是使用 current。如何在不移动指针的情况下查看数组中的下一项?读到这个问题,我写了这篇文章:
foreach($creds as $cred){
echo $cred['tipo'];
//if the next item has a 'tipo' key with a specific value
if(current($creds['tipo'])!='4'){
echo 'Total';
}
}
但这行不通。如何解决?
编辑:根据答案,我将在下一次迭代的开始时移动回声"总计"内容,而不是当前迭代的底部。据我在答案中看到,没有其他使用 foreach 的解决方案
要求是:
- 在
foreach
循环内查看next
值或键,但不更改foreach
循环的current
迭代器指针的位置。
虽然它是更多的代码,但一种方法是在同一数组上创建一个完全独立的迭代器。
这个新iterator
必须与foreach
循环保持同步,但这很简单。
优点是你可以使用next()
、prev()
、current()
等来操纵任何你想要的方式,并且知道foreach
循环不会受到影响。
对于此示例,要求在当前条目之前测试下一个条目。从指向第二个条目的迭代器开始,每次都前进是值得的。
例如,未经测试的代码...
$iter = new 'ArrayIterator($cred)s; // mirror of the `foreach` loop
迭 代 foreach($creds as $cred) {
// get next key and value...
$iter->next();
$nextKey = $iter->key();
$nextValue = $iter->current();
echo $cred['tipo'];
// if the next item has a 'tipo' key with a specific value
if($nextValue['tipo']) != '4'){
echo 'Total';
}
}
试试这段代码
$keys = array_keys($creds);
for($i = 0; $i < sizeof($keys); $i++)
{
echo $creds[$keys[$i]] .' ';
//$creds[$keys[$i+1]] - next item
if($keys[$i+1] == 'tipo' && $creds[$keys[$i+1]] == 4 )
{
//
}
}
我会在每个循环中检查当前项目是否具有您的特殊键/值对,然后在最后再检查一次。这样,您就不必访问下一项(并前后移动指针)。如果它比echo 'Total';
复杂,那么你可以把它包装到一个函数中,以避免在foreach
循环中和之后重复代码。
$creds = [
['tipo' => '1'],
['tipo' => '2'],
['tipo' => '3'],
['tipo' => '4'],
['tipo' => '5'],
];
foreach ($creds as $cred) {
if ($cred['tipo'] == '4') {
echo "Total'n";
}
echo $cred['tipo'] . "'n";
}
// If the very last row had the special key, print the sum one more time
if ($cred['tipo'] == '4') {
echo "Total'n";
}
/* Output:
1
2
3
Total
4
5
*/
编辑:
我误解了您的要求("如果数组中的下一个元素与特定条件匹配,我想在数组中的每个项目之后放置一个总计行")。如果你想要相反的方式,我建议,在变量$previous_row
中"缓冲"当前行的值,直到foreach
循环向前移动指针并且你能够访问和检查值:
$creds = [
['tipo' => '1'],
['tipo' => '2'],
['tipo' => '3'],
['tipo' => '4'],
['tipo' => '5'],
];
$previous_row = '';
foreach ($creds as $cred) {
echo $previous_row;
if ($previous_row && $cred['tipo'] != '4') {
echo "Total'n";
}
$previous_row = $cred['tipo'] . "'n";
}
// If the very last row had the special key, print the sum one more time
echo $previous_row;
if ($cred['tipo'] != '4') {
echo "Total'n";
}
/* Output:
1
Total
2
Total
3
4
Total
5
Total
*/
使用next后,您可以尝试使用prev函数。这可能不是最好的解决方案,但它应该有效。
$values = array(1,2,3);
foreach ($values as $a) {
print next($values);
prev();
}
应输出 2,3
编辑
实际上 next() 在执行后不会影响您的循环键,并为您提供下一个值。在回答您提供的链接时也注意到了这一点。您还可以使用自定义迭代器和 prev 函数手动更改迭代。http://php.net/manual/en/language.oop5.iterations.php
<?php
class MyIterator implements Iterator
{
private $var = array();
public function __construct($array)
{
if (is_array($array)) {
$this->var = $array;
}
}
public function rewind()
{
reset($this->var);
}
public function current()
{
$var = current($this->var);
return $var;
}
public function key()
{
$var = key($this->var);
return $var;
}
public function next()
{
$var = next($this->var);
return $var;
}
public function prev()
{
$var = prev($this->var);
return $var;
}
public function valid()
{
$key = key($this->var);
$var = ($key !== NULL && $key !== FALSE);
return $var;
}
}
$values = array(1,2,3);
$it = new MyIterator($values);
foreach ($it as $a => $b) {
print 'next is '.$it->next();
$it->prev();
}
?>