在PHP中使用foreach循环时查找数组的最后一个元素
我正在写一个SQL查询创build者使用一些参数。 在Java中,通过使用数组长度检查当前数组的位置,可以非常容易地从for循环中检测数组的最后一个元素。
for(int i=0; i< arr.length;i++){ boolean isLastElem = i== (arr.length -1) ? true : false; }
在PHP中,他们有非整数索引来访问数组。 所以你必须使用foreach循环迭代一个数组。 当你需要做出一些决定(在我的情况下追加或/和参数,同时构build查询)这成为问题。
我确定必须有一些标准的做法。
你如何在PHP中解决这个问题?
这听起来像你想要这样的事情:
$numItems = count($arr); $i = 0; foreach($arr as $key=>$value) { if(++$i === $numItems) { echo "last index!"; } }
这就是说,你不需要 – 在PHP中使用foreach
遍历一个“数组”。
您可以使用end(array_keys($array))
获取数组最后一个键的值,并将其与当前键进行比较:
$last_key = end(array_keys($array)); foreach ($array as $key => $value) { if ($key == $last_key) { // last element } else { // not last element } }
为什么这么复杂?
foreach($input as $key => $value) { $ret .= "$value"; if (next($input)==true) $ret .= ","; }
除了最后一个值之外,这将会增加一个值。
当toEnd达到0时,意味着它在循环的最后迭代。
$toEnd = count($arr); foreach($arr as $key=>$value) { if (0 === --$toEnd) { echo "last index! $value"; } }
最后一个值在循环之后仍然可用,所以如果你只是想在循环之后使用它更多的东西,这是更好的:
foreach($arr as $key=>$value) { //something } echo "last index! $key => $value";
如果你不想把最后一个值作为特殊的内部循环。 如果你有大数组,这应该会更快。 (如果在同一范围内的循环之后重用数组,则必须先“复制”数组)。
//If you use this in a large global code without namespaces or functions then you can copy the array like this: //$array = $originalArrayName; //uncomment to copy an array you may use after this loop //end($array); $lastKey = key($array); //uncomment if you use the keys $lastValue = array_pop($array); //do something special with the last value here before you process all the others? echo "Last is $lastValue", "\n"; foreach ($array as $key => $value) { //do something with all values before the last value echo "All except last value: $value", "\n"; } //do something special with the last value here after you process all the others? echo "Last is $lastValue", "\n";
并回答你原来的问题“在我的情况下追加或/和build立查询参数”; 这将循环所有的值,然后将它们连接在一起,以便在它们之间有一个“and”string,但不能在第一个值之前或最后一个值之后:
$params = []; foreach ($array as $value) { $params[] = doSomething($value); } $parameters = implode(" and ", $params);
已经有很多的答案了,但是也应该看一下迭代器,特别是要求有一个标准的方法:
$arr = range(1, 3); $it = new CachingIterator(new ArrayIterator($arr)); foreach($it as $key => $value) { if (!$it->hasNext()) echo 'Last:'; echo $value, "\n"; }
你可能会发现一些对其他情况更灵活的东西。
所以,如果你的数组有独特的数组值,那么确定最后的迭代是微不足道的:
foreach($array as $element) { if ($element === end($array)) echo 'LAST ELEMENT!'; }
正如你所看到的,如果最后一个元素在数组中出现一次,这将工作,否则你会得到一个错误的警报。 在这不是,你必须比较键(这是唯一的肯定)。
foreach($array as $key => $element) { end($array); if ($key === key($array)) echo 'LAST ELEMENT!'; }
还要注意严格的共同操作符,在这种情况下非常重要。
假设你有一个数组存储在一个variables…
foreach($array as $key=>$value) { echo $value; if($key != count($array)-1) { echo ", "; } }
如果您需要为除了第一个或最后一个元素之外的每个元素执行一些操作,并且仅当数组中有多个元素时,我更喜欢以下解决scheme。
我知道上面有很多解决scheme,并且在我的月份/一年之前发布,但是这是我觉得相当优雅的事情。 检查每个循环也是一个布尔检查,而不是数字“我=(count-1)”检查,这可能会减less开销。
循环的结构可能会感到尴尬,但您可以将它与HTML表格标记中的add(开始),tfoot(end),tbody(current)的顺序进行比较。
$first = true; foreach($array as $key => $value) { if ($first) { $first = false; // Do what you want to do before the first element echo "List of key, value pairs:\n"; } else { // Do what you want to do at the end of every element // except the last, assuming the list has more than one element echo "\n"; } // Do what you want to do for the current element echo $key . ' => ' . $value; }
例如,在web开发方面,如果你想在无序列表(ul)中为除了最后一个元素之外的每个元素添加一个border-bottom ,那么你可以添加一个border-top到除第一个元素 (CSS:第一个孩子,在IE7 +和Firefox / Webkit的支持下支持这个逻辑,而最后一个孩子不被IE7支持)。
你可以自由地为每一个嵌套循环重复使用$ firstvariables,因为每个循环在第一次迭代的第一个过程中使得$首先是错误的(所以break / exceptions不会引起问题) 。
$first = true; foreach($array as $key => $subArray) { if ($first) { $string = "List of key => value array pairs:\n"; $first = false; } else { echo "\n"; } $string .= $key . '=>('; $first = true; foreach($subArray as $key => $value) { if ($first) { $first = false; } else { $string .= ', '; } $string .= $key . '=>' . $value; } $string .= ')'; } echo $string;
示例输出:
List of key => value array pairs: key1=>(v1_key1=>v1_val1, v1_key2=>v1_val2) key2=>(v2_key1=>v2_val1, v2_key2=>v2_val2, v2_key3=>v2_val3) key3=>(v3_key1=>v3_val1)
这应该是find最后一个元素的简单方法:
foreach ( $array as $key => $a ) { if ( end( array_keys( $array ) ) == $key ) { echo "Last element"; } else { echo "Just another element"; } }
参考: 链接
您仍然可以在关联数组中使用该方法:
$keys = array_keys($array); for ($i = 0, $l = count($array); $i < $l; ++$i) { $key = $array[$i]; $value = $array[$key]; $isLastItem = ($i == ($l - 1)); // do stuff } // or this way... $i = 0; $l = count($array); foreach ($array as $key => $value) { $isLastItem = ($i == ($l - 1)); // do stuff ++$i; }
我有一个强烈的感觉,在这个“XY问题”的根源,OP想要implode()
函数。
这听起来像你想要这样的事情:
$array = array( 'First', 'Second', 'Third', 'Last' ); foreach($array as $key => $value) { if(end($array) === $value) { echo "last index!" . $value; } }
因为你寻找EOF数组的意图只是为了胶水。 介绍下面的战术。 你不需要EOF:
$given_array = array('column1'=>'value1', 'column2'=>'value2', 'column3'=>'value3'); $glue = ''; foreach($given_array as $column_name=>$value){ $where .= " $glue $column_name = $value"; //appending the glue $glue = 'AND'; } echo $where;
O / P:
column1 = value1 AND column2 = value2 AND column3 = value3
你可以做一个count()。
for ($i=0;$i<count(arr);$i++){ $i == count(arr)-1 ? true : false; }
或者如果您只查找最后一个元素,则可以使用end()。
end(arr);
只返回最后一个元素。
事实certificate,你可以通过整数索引php数组。 这非常开心
arr[1];
你也可以做这样的事情:
end( $elements ); $endKey = key($elements); foreach ($elements as $key => $value) { if ($key == $endKey) // -- this is the last item { // do something } // more code }
我有点像以下,因为我觉得这是相当整洁。 假设我们在所有元素之间创build一个带有分隔符的string:例如a,b,c
$first = true; foreach ( $items as $item ) { $str = ($first)?$first=false:", ".$item; }
一种方法可能是检测迭代器是否有next
。 如果没有下一个附加到迭代器,这意味着你在最后一个循环。
foreach ($some_array as $element) { if(!next($some_array)) { // This is the last $element } }
这是另一种方法,你可以做到这一点:
$arr = range(1, 10); $end = end($arr); reset($arr); while( list($k, $v) = each($arr) ) { if( $n == $end ) { echo 'last!'; } else { echo sprintf('%s ', $v); } }
如果我理解你,那么你所需要的就是颠倒数组,并通过popup命令获取最后一个元素:
$rev_array = array_reverse($array); echo array_pop($rev_array);
你也可以试试这个让你的查询在这里用INSERT显示
<?php $week=array('one'=>'monday','two'=>'tuesday','three'=>'wednesday','four'=>'thursday','five'=>'friday','six'=>'saturday','seven'=>'sunday'); $keys = array_keys($week); $string = "INSERT INTO my_table ('"; $string .= implode("','", $keys); $string .= "') VALUES ('"; $string .= implode("','", $week); $string .= "');"; echo $string; ?>
对于SQL查询生成脚本,或者对第一个或最后一个元素执行不同操作的任何操作,要避免使用不必要的variables检查,速度要快得多(快近两倍)。
目前接受的解决scheme在循环中使用循环和检查,将进行every_single_iteration,正确(快速)的方法是这样的:
$numItems = count($arr); $i=0; $firstitem=$arr[0]; $i++; while($i<$numItems-1){ $some_item=$arr[$i]; $i++; } $last_item=$arr[$i]; $i++;
一个自制的基准testing显示如下:
test1:模型morg的100000次运行
时间:1869.3430423737毫秒
test2:如果最后一次运行100000次模型
时间:3235.6359958649毫秒
另一种方法是记住以前的循环结果并将其用作最终结果:
$result = $where = ""; foreach ($conditions as $col => $val) { $result = $where .= $this->getAdapter()->quoteInto($col.' = ?', $val); $where .= " AND "; } return $this->delete($result);
我个人使用这种结构,使用html <ul>和<li>元素很容易使用:只需更改其他属性的等式…
该数组不能包含错误的项目,但所有其他项目被投入到假的布尔值。
$table = array( 'a' , 'b', 'c'); $it = reset($table); while( $it !== false ) { echo 'all loops';echo $it; $nextIt = next($table); if ($nextIt === false || $nextIt === $it) { echo 'last loop or two identical items'; } $it = $nextIt; }
你可以通过以下方式直接得到最后的索引:
$numItems = count($arr);
echo $arr[$numItems-1];
<?php foreach($have_comments as $key => $page_comment): ?> <?php echo $page_comment;?> <?php if($key+1<count($have_comments)): ?> <?php echo ', '; ?> <?php endif;?> <?php endforeach;?>
这是我的解决scheme:简单地得到你的数组减1(因为他们从0开始)。
$lastkey = count($array) - 1; foreach($array as $k=>$a){ if($k==$lastkey){ /*do something*/ } }
我有一个通用的解决scheme,我使用,为了从string值数组编译string的共同目的。 我所做的只是添加一个不寻常的string到最后,然后将其replace。
函数从数组中返回一个string,分隔,没有尾随分隔符:
function returnArraySeparated($aArr, $sSep, $sAdd = "@X@") { $strReturn = (string) ""; # Compile the set: foreach ($aArr as $sItem) { $strReturn .= $sItem . $sSep; } # Easy strip the end: $strReturn = str_replace($sSep . $sAdd, "", $strReturn . $sAdd); return $strReturn; }
没什么特别的,但它的作品:)