Câu trả lời:
Bạn có thể sử dụng một bộ đếm:
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
$i = 1
, bạn không phải lo lắng $len - 1
, chỉ cần sử dụng $len
.
Nếu bạn thích một giải pháp không yêu cầu khởi tạo bộ đếm bên ngoài vòng lặp, tôi đề nghị so sánh khóa lặp hiện tại với hàm cho bạn biết khóa cuối / đầu tiên của mảng.
Điều này trở nên hiệu quả hơn (và dễ đọc hơn) với PHP 7.3 sắp tới.
foreach($array as $key => $element) {
if ($key === array_key_first($array))
echo 'FIRST ELEMENT!';
if ($key === array_key_last($array))
echo 'LAST ELEMENT!';
}
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()
trên mỗi lần lặp của vòng lặp - nếu đó là cả hai thì đó là 4 phương thức được gọi mỗi lần. Cấp, đó sẽ là các hoạt động rất nhẹ và có lẽ chỉ là tra cứu con trỏ, nhưng sau đó các tài liệu tiếp tục chỉ định điều đó reset()
và end()
sửa đổi con trỏ bên trong của mảng - vì vậy nó có nhanh hơn bộ đếm không? có thể không
reset()
cuộc gọi trước khi foreach và lưu kết quả vào bộ đệm $first
.
Để tìm mục cuối cùng, tôi thấy đoạn mã này hoạt động mỗi lần:
foreach( $items as $item ) {
if( !next( $items ) ) {
echo 'Last Item';
}
}
[true,true,false,true]
. Nhưng cá nhân tôi sẽ sử dụng điều này bất cứ khi nào tôi đang xử lý một mảng không chứa boolean false
.
next()
nên KHÔNG BAO GIỜ được sử dụng bên trong một vòng lặp foreach. Nó làm rối con trỏ mảng bên trong. Kiểm tra các tài liệu để biết thêm.
Một phiên bản đơn giản hơn ở trên và cho rằng bạn không sử dụng các chỉ mục tùy chỉnh ...
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
} else if ($index == $len - 1) {
// last
}
}
Phiên bản 2 - Bởi vì tôi đã không thích sử dụng cái khác trừ khi cần thiết.
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
// do something
continue;
}
if ($index == $len - 1) {
// last
// do something
continue;
}
}
if ($index == count($array) - 1)
. Xem ở đây .
Bạn có thể loại bỏ các phần tử đầu tiên và cuối cùng ra khỏi mảng và xử lý chúng một cách riêng biệt.
Như thế này:
<?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
?>
Xóa tất cả định dạng sang CSS thay vì thẻ nội tuyến sẽ cải thiện mã của bạn và tăng tốc thời gian tải.
Bạn cũng có thể tránh trộn HTML với logic php bất cứ khi nào có thể.
Trang của bạn có thể được làm cho dễ đọc và dễ bảo trì hơn rất nhiều bằng cách tách những thứ như thế này:
<?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
}
?>
Một nỗ lực để tìm kiếm đầu tiên sẽ là:
$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
}
}
Đơn giản là điều này hoạt động!
// 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];
}
Cảm ơn bạn @billynoah vì đã giải quyết vấn đề cuối cùng .
if ($key === $lastkey)
.
if ($lastkey === $key)
sao?
PHP Warning: key() expects parameter 1 to be array, integer given in php shell code on line 1
key()
đang nhận được một số nguyên, không end()
. end()
"Trả về giá trị của phần tử cuối cùng " và key()
mong đợi một mảng làm đầu vào.
1: Tại sao không sử dụng một for
tuyên bố đơn giản ? Giả sử bạn đang sử dụng một mảng thực sự chứ không phải một mảng Iterator
bạn có thể dễ dàng kiểm tra xem biến đếm là 0 hay một ít hơn toàn bộ số phần tử. Theo tôi đây là giải pháp sạch sẽ và dễ hiểu nhất ...
$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: Bạn nên cân nhắc sử dụng Bộ lồng để lưu trữ cấu trúc cây của bạn. Ngoài ra, bạn có thể cải thiện toàn bộ bằng cách sử dụng các hàm đệ quy.
for
bạn có thể lặp từ 1
đến n-1
và lấy if
s ra khỏi cơ thể. Không có điểm kiểm tra chúng nhiều lần.
Câu trả lời tốt nhất:
$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";
}
Câu trả lời hiệu quả nhất từ @morg, không giống như foreach
, chỉ hoạt động cho các mảng thích hợp, không phải là các đối tượng bản đồ băm. Câu trả lời này tránh được chi phí chung của một câu lệnh có điều kiện cho mỗi lần lặp của vòng lặp, như trong hầu hết các câu trả lời này (bao gồm cả câu trả lời được chấp nhận) một cách cụ thể xử lý phần tử đầu tiên và cuối cùng, và lặp qua các phần tử ở giữa.
Các array_keys
chức năng có thể được sử dụng để thực hiện các công việc trả lời hiệu quả như 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++;
Tôi đã không thực hiện đo điểm chuẩn về điều này, nhưng không có logic nào được thêm vào vòng lặp, đó là điểm nhấn lớn nhất đối với hiệu suất xảy ra, vì vậy tôi nghi ngờ rằng các điểm chuẩn được cung cấp với câu trả lời hiệu quả là khá gần.
Nếu bạn muốn chức năng hóa loại điều này, tôi đã thực hiện một cú swing tại hàm iterateList như vậy ở đây . Mặc dù, bạn có thể muốn điểm chuẩn mã chính nếu bạn cực kỳ quan tâm đến hiệu quả. Tôi không chắc chắn bao nhiêu chi phí mà tất cả các lời gọi hàm giới thiệu.
Đối với các tập lệnh tạo truy vấn SQL hoặc bất kỳ tập lệnh nào thực hiện hành động khác nhau cho các phần tử đầu tiên hoặc cuối cùng, sẽ nhanh hơn nhiều (gần gấp đôi nhanh) để tránh sử dụng kiểm tra biến không cần thiết.
Giải pháp được chấp nhận hiện tại sử dụng một vòng lặp và kiểm tra trong vòng lặp sẽ được thực hiện every_single_iteration, cách chính xác (nhanh) để làm điều này là như sau:
$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
$some_item=$arr[$i];
$i++;
}
$last_item=$arr[$i];
$i++;
Một chút điểm chuẩn tự chế cho thấy như sau:
test1: 100000 lần chạy mô hình
thời gian: 1869.3430423737 mili giây
test2: 100000 lần chạy mô hình nếu kéo dài
thời gian: 3235.6359958649 mili giây
Và do đó, khá rõ ràng rằng séc chi phí rất nhiều, và tất nhiên nó thậm chí còn tệ hơn khi bạn kiểm tra nhiều biến hơn;)
$arr = array('one' => "1 1 1", 4 => 'Four', 1 => 'One'); $numItems = count($arr); $i=0; $firstitem=$arr[0]; echo $i . ': ' . $firstitem . ", "; $i++; while($i<$numItems-1){ $some_item=$arr[$i]; echo $i . ': ' . $some_item . ", "; $i++; } $last_item=$arr[$i]; echo $i . ': ' . $last_item . ", "; $i++;
sẽ xuất:0: , 1: One, 2: ,
array()
được tạo ra {'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}
nhưng các phần tử trống bị bỏ qua với số đếm, bạn đang đếm số lượng "điều" được xác định !! TUYỆT VỜI TUYỆT VỜI! Câu trả lời này xứng đáng nhận tiền thưởng, nhưng nếu @Morg. biến mất, nó là vô nghĩa. Tôi sẽ đưa tiền thưởng cho một người có thể sẽ không sử dụng SO nữa! Nếu anh ta trở lại và cải thiện câu trả lời của mình, anh ta xứng đáng nhận được tiền thưởng!
array_keys
hàm, mà bạn có thể coi như một mảng. Xem câu trả lời "cải tiến" của tôi .
$querySet = ""; foreach ($fieldSet as $key=>$value) { $value = $db->dbLink->quote($value); $querySet .= "$key = $value, "; } $querySet = substr_replace($querySet, "", -2); $queryString = "UPDATE users SET $querySet WHERE user_ID = '$user_ID'";
Với Khóa và Giá trị, điều này cũng hoạt động:
foreach ($array as $key => $value) {
if ($value === end($array)) {
echo "LAST ELEMENT!";
}
}
Sử dụng biến Boolean vẫn đáng tin cậy nhất, ngay cả khi bạn muốn kiểm tra sự xuất hiện đầu tiên của một $value
(tôi thấy nó hữu ích hơn trong tình huống của tôi và trong nhiều tình huống) , như thế này:
$is_first = true;
foreach( $array as $value ) {
switch ( $value ) {
case 'match':
echo 'appeared';
if ( $is_first ) {
echo 'first appearance';
$is_first = false;
}
break;
}
}
if( !next( $array ) ) {
echo 'last value';
}
}
Sau đó, làm thế nào !next( $array )
để tìm cái cuối cùng $value
sẽ trả về true
nếu không có next()
giá trị để lặp lại.
Và tôi thích sử dụng một for
vòng lặp thay vì foreach
nếu tôi sẽ sử dụng một bộ đếm, như thế này:
$len = count( $array );
for ( $i = 0; $i < $len; $i++ ) {
$value = $array[$i];
if ($i === 0) {
// first
} elseif ( $i === $len - 1 ) {
// last
}
// …
$i++;
}
Tôi đã đi qua chủ đề này khi tôi có cùng một vấn đề. Tôi chỉ cần lấy phần tử đầu tiên sau đó tôi phân tích lại mã của mình cho đến khi điều này xuất hiện trong đầu tôi.
$firstElement = true;
foreach ($reportData->result() as $row)
{
if($firstElement) { echo "first element"; $firstElement=false; }
// Other lines of codes here
}
Các mã trên là tuyệt vời và đầy đủ nhưng nếu bạn chỉ cần yếu tố đầu tiên thì bạn có thể thử mã này.
Không chắc chắn nếu nó vẫn cần thiết. Nhưng giải pháp sau đây nên làm việc với các trình vòng lặp và không yêu cầu count
.
<?php
foreach_first_last(array(), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
foreach_first_last(array('aa'), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;
foreach_first_last(array('aa', 'bb', 'cc'), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;
function foreach_first_last($array, $cb)
{
$next = false;
$current = false;
reset($array);
for ($step = 0; true; ++$step) {
$current = $next;
$next = each($array);
$last = ($next === false || $next === null);
if ($step > 0) {
$first = $step == 1;
list ($key, $value) = $current;
if (call_user_func($cb, $key, $value, $step, $first, $last) === false) {
break;
}
}
if ($last) {
break;
}
}
}
Bạn cũng có thể sử dụng một chức năng ẩn danh:
$indexOfLastElement = count($array) - 1;
array_walk($array, function($element, $index) use ($indexOfLastElement) {
// do something
if (0 === $index) {
// first element‘s treatment
}
if ($indexOfLastElement === $index) {
// last not least
}
});
Ba điều nữa cần được đề cập:
array_values
.$element
bạn phải vượt qua nó bằng cách tham khảo (&$element
).$indexOfLastElement
bên trong use
cấu trúc, theo tham chiếu nếu cần.Bạn có thể sử dụng bộ đếm và chiều dài mảng.
$ mảng = mảng (1,2,3,4); $ i = 0; $ len = đếm (mảng $); foreach ($ mảng là $ item) { if ($ i === 0) { // Đầu tiên } khác nếu ($ i === $ len - 1) { // Cuối cùng } // $ i ++; }
foreach ($arquivos as $key => $item) {
reset($arquivos);
// FIRST AHEAD
if ($key === key($arquivos) || $key !== end(array_keys($arquivos)))
$pdf->cat(null, null, $key);
// LAST
if ($key === end(array_keys($arquivos))) {
$pdf->cat(null, null, $key)
->execute();
}
}
Sử dụng thiết lập lại (mảng $) và kết thúc ($ mảng)
<?php
$arrays = [1,2,3,4,5];
$first = reset($arrays);
$last = end($arrays);
foreach( $arrays as $array )
{
if ( $first == $array )
{
echo "<li>{$array} first</li>";
}
else if ( $last == $array )
{
echo "<li>{$array} last</li>";
}
else
{
echo "<li>{$array}</li>";
}
}
Thử cái này:
function children( &$parents, $parent, $selected ){
if ($parents[$parent]){
$list = '<ul>';
$counter = count($parents[$parent]);
$class = array('first');
foreach ($parents[$parent] as $child){
if ($child['id'] == $selected) $class[] = 'active';
if (!--$counter) $class[] = 'last';
$list .= '<li class="' . implode(' ', $class) . '"><div><a href="]?id=' . $child['id'] . '" alt="' . $child['name'] . '">' . $child['name'] . '</a></div></li>';
$class = array();
$list .= children($parents, $child['id'], $selected);
}
$list .= '</ul>';
return $list;
}
}
$output .= children( $parents, 0, $p_industry_id);
array_shift
vàarray_pop
. Mặc dù đây là giải pháp tôi đã đưa ra nếu tôi phải thực hiện một điều như vậy, tôi vẫn kiên trì với câu trả lời của Rok Kralj ngay bây giờ.