这个问题很简单。我在我的代码中有一个foreach
循环:
foreach($array as $element) {
//code
}
在这个循环中,我想在第一次或最后一次迭代时有不同的反应。如何实现?如果您希望一种不需要在循环外部初始化计数器的解决方案,那么可以将当前迭代键与函数进行比较,该函数告诉您数组的最后/第一个键。
foreach ($array as $key => $element) {
if ($key === array_key_first($array)) {
echo 'FIRST ELEMENT!';
}
if ($key === array_key_last($array)) {
echo 'LAST ELEMENT!';
}
}
PHP 7.2已经到达生命周期结束(EOL),因此此处仅用于历史参考。建议避免使用。
foreach ($array as $key => $element) {
reset($array);
if ($key === key($array)) {
echo 'FIRST ELEMENT!';
}
end($array);
if ($key === key($array)) {
echo 'LAST ELEMENT!';
}
}
end()
+ key()
- 如果两个都包含,那么每次循环需要调用4个方法。尽管如此,这些操作非常轻量级,并且可能只是指针查找,但是文档确实继续指定 reset()
和 end()
会修改数组的内部指针 - 所以它比计数器更快吗?可能不是。 - pospiforeach
方法会在数组的一个副本上进行操作,因此是可行的。但如果您还有顾虑的话,可以将 reset()
方法调用放在 foreach
之前,并将结果缓存到 $first
中。 - Rok Kralj你可以使用一个计数器:
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
array_shift
和array_pop
那样糟糕。虽然如果我必须实现这样一件事情,这就是我想出来的解决方案,但现在我会坚持Rok Kralj的答案。 - shadyyx$i = 1
,就不必担心 $len - 1
,只需使用 $len
。 - aksu我发现以下代码每次都能找到最后一个项目:
foreach( $items as $item ) {
if( !next( $items ) ) {
echo 'Last Item';
}
}
FALSE
**,但也可能返回一个被评估为 FALSE
的非布尔值。请阅读有关布尔值的章节以获取更多信息。在测试此函数的返回值时,请使用 ===
运算符。 - Pang[true,true,false,true]
这样的数组。但就个人而言,只要处理不包含布尔值false
的数组,我将随时使用它。 - But those new buttons though..next()
函数,它会破坏内部数组指针。请查看文档以获取更多信息。 - Ian Hazzard以下是更简化的版本,假设您没有使用自定义索引...
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
} else if ($index == $len - 1) {
// last
}
}
版本2 - 因为我已经厌倦了除非必要否则使用else。
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
// do something
continue;
}
if ($index == $len - 1) {
// last
// do something
continue;
}
}
代码
<?php
$array = something();
$first = array_shift($array);
$last = array_pop($array);
// do something with $first
foreach ($array as $item) {
// do something with $item
}
// do something with $last
?>
将所有格式设置为CSS而不是内联标签可以改善您的代码并加快加载时间。
尽可能避免将HTML与PHP逻辑混合。
通过分离像这样的内容,可以使您的页面更易读和可维护:
<?php
function create_menu($params) {
//retrieve menu items
//get collection
$collection = get('xxcollection') ;
foreach($collection as $c) show_collection($c);
}
function show_subcat($val) {
?>
<div class="sub_node" style="display:none">
<img src="../images/dtree/join.gif" align="absmiddle" style="padding-left:2px;" />
<a id="'.$val['xsubcatid'].'" href="javascript:void(0)" onclick="getProduct(this , event)" class="sub_node_links" >
<?php echo $val['xsubcatname']; ?>
</a>
</div>
<?php
}
function show_cat($item) {
?>
<div class="node" >
<img src="../images/dtree/plus.gif" align="absmiddle" class="node_item" id="plus" />
<img src="../images/dtree/folder.gif" align="absmiddle" id="folder">
<?php echo $item['xcatname']; ?>
<?php
$subcat = get_where('xxsubcategory' , array('xcatid'=>$item['xcatid'])) ;
foreach($subcat as $val) show_subcat($val);
?>
</div>
<?php
}
function show_collection($c) {
?>
<div class="parent" style="direction:rtl">
<img src="../images/dtree/minus.gif" align="absmiddle" class="parent_item" id="minus" />
<img src="../images/dtree/base.gif" align="absmiddle" id="base">
<?php echo $c['xcollectionname']; ?>
<?php
//get categories
$cat = get_where('xxcategory' , array('xcollectionid'=>$c['xcollectionid']));
foreach($cat as $item) show_cat($item);
?>
</div>
<?php
}
?>
简单来说,这个很有效!
// Set the array pointer to the last key
end($array);
// Store the last key
$lastkey = key($array);
foreach($array as $key => $element) {
....do array stuff
if ($lastkey === key($array))
echo 'THE LAST ELEMENT! '.$array[$lastkey];
}
感谢@billynoah解决了最后问题。
if ($key === $lastkey)
这行代码。 - Krzysztof Przygodaif ($lastkey === $key)
吗? - KineticPHP Warning: key() expects parameter 1 to be array, integer given in php shell code on line 1
。 - But those new buttons though..key()
接收的是一个整数,而不是end()
。end()
“返回最后一个元素的值”,而key()
需要输入一个数组。 - But those new buttons though..尝试寻找第一个的方法是:
$first = true;
foreach ( $obj as $value )
{
if ( $first )
{
// do something
$first = false; //in order not to get into the if statement for the next loops
}
else
{
// do something else for all loops except the first
}
}
1:为什么不使用简单的for
语句?假设您正在使用真实数组而不是Iterator
,您可以轻松检查计数器变量是否为0或比整个元素数量少1。在我看来,这是最清晰易懂的解决方案...
$array = array( ... );
$count = count( $array );
for ( $i = 0; $i < $count; $i++ )
{
$current = $array[ $i ];
if ( $i == 0 )
{
// process first element
}
if ( $i == $count - 1 )
{
// process last element
}
}
2:你应该考虑使用嵌套集来存储你的树形结构。此外,你可以通过使用递归函数来改进整个过程。
for
循环,可以从 1
循环到 n-1
,并将 if
语句移出循环体。重复检查它们没有意义。 - mpen最佳答案:
$arr = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
foreach ($arr as $a) {
// This is the line that does the checking
if (!each($arr)) echo "End!\n";
echo $a."\n";
}
最有效的答案来自@morg,与foreach
不同,它仅适用于适当的数组,而不是哈希映射对象。该答案避免了在循环的每次迭代中进行条件语句的开销,如大多数答案(包括被接受的答案)具体地处理第一个和最后一个元素,并循环处理中间元素。
array_keys
函数可用于使高效答案像foreach
一样工作:
$keys = array_keys($arr);
$numItems = count($keys);
$i=0;
$firstItem=$arr[$keys[0]];
# Special handling of the first item goes here
$i++;
while($i<$numItems-1){
$item=$arr[$keys[$i]];
# Handling of regular items
$i++;
}
$lastItem=$arr[$keys[$i]];
# Special handling of the last item goes here
$i++;