Yanıtlar:
Bir sayaç kullanabilirsiniz:
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
$i = 1
, endişelenmene gerek yok $len - 1
, sadece kullan $len
.
Sayacın döngü dışında başlatılmasını gerektirmeyen bir çözümü tercih ederseniz, geçerli yineleme anahtarını size dizinin son / ilk anahtarını söyleyen işlevle karşılaştırmayı öneririm.
Bu, yaklaşan PHP 7.3 ile biraz daha verimli (ve daha okunabilir) hale geliyor.
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()
+ dır key()
- eğer ikisi de ise her seferinde 4 yöntem denir. Bu çok hafif işlemler olacak ve muhtemelen sadece işaretçi aramaları olacak, ancak dokümanlar bunu belirtmek reset()
ve dizinin dahili işaretçisini end()
değiştirmek için devam ediyor - bu yüzden bir sayaçtan daha mı hızlı? muhtemelen hayır.
reset()
çağrıyı foreach'ten önce taşıyın ve sonucu önbelleğe alın $first
.
Son öğeyi bulmak için, bu kod parçasının her seferinde işe yaradığını görüyorum:
foreach( $items as $item ) {
if( !next( $items ) ) {
echo 'Last Item';
}
}
[true,true,false,true]
. Ama şahsen ben boolean içermeyen bir dizi ile ilgileniyorum zaman kullanacağım false
.
next()
gereken hiçbir zaman bir foreach döngü içinde kullanılabilir. Dahili dizi işaretçisini karıştırır. Daha fazla bilgi için belgelere bakın.
Yukarıdakilerin daha basitleştirilmiş bir sürümü ve özel dizinler kullanmadığınız varsayılıyor ...
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
} else if ($index == $len - 1) {
// last
}
}
Sürüm 2 - Çünkü gerekmedikçe başkalarını kullanarak tiksinmeye geldim.
$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)
. Buraya bakın .
Dizideki ilk ve son öğeleri kaldırabilir ve ayrı ayrı işleyebilirsiniz.
Bunun gibi:
<?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
?>
Satır içi etiketler yerine tüm biçimlendirmeyi kaldırmak, kodunuzu iyileştirir ve yükleme süresini hızlandırır.
Mümkün olduğunda HTML'yi php logic ile karıştırmaktan da kaçınabilirsiniz.
Sayfanız, bunun gibi şeyleri ayırarak çok daha okunabilir ve sürdürülebilir hale getirilebilir:
<?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
}
?>
İlkini bulma girişimi:
$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
}
}
Basitçe bu işe yarıyor!
// 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];
}
Son sorunu çözdüğünüz için @billynoah'a teşekkür ederiz .
if ($key === $lastkey)
.
if ($lastkey === $key)
mı?
PHP Warning: key() expects parameter 1 to be array, integer given in php shell code on line 1
key()
tamsayı alıyor, değil end()
. end()
" son elemanın değerini döndürür " ve key()
bir dizi girdi olarak bekler.
1: Neden basit bir for
ifade kullanmıyorsunuz ? Gerçek bir dizi kullandığınızı varsayarsak Iterator
, sayaç değişkeninin 0 veya tüm eleman sayısından daha az olup olmadığını kolayca kontrol edebilirsiniz. Bence bu en temiz ve anlaşılır çözüm ...
$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: Ağaç yapınızı saklamak için İç İçe Kümeler kullanmayı düşünmelisiniz . Ayrıca, özyinelemeli işlevler kullanarak her şeyi iyileştirebilirsiniz.
for
geçebilir ve s'yi alabilirsiniz . Tekrar tekrar kontrol etmenin bir anlamı yok. 1
n-1
if
En iyi cevap:
$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'un en etkili cevabı , aksine foreach
, sadece harita dizileri için çalışır, karma harita nesneleri için değil. Bu yanıt , ilk ve son öğeyi özel olarak işleyerek ve orta elemanlar üzerinde döngü yaparak bu yanıtların çoğunda (kabul edilen cevap dahil) olduğu gibi, döngünün her yinelemesi için koşullu bir ifadenin ek yükünü önler .
array_keys
Fonksiyonu gibi verimli cevap çalışması için kullanılabilir 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++;
Bu konuda bir kıyaslama yapmadım, ancak döngüye hiçbir mantık eklenmedi, bu da performansa en büyük hit oldu, bu yüzden verimli cevapla sağlanan kriterlerin oldukça yakın olduğundan şüpheleniyorum.
Eğer isteseydim işlevselleştirmek bu tür şeyleri, böyle bir bir yumruk attık burada iterateList fonksiyonu . Bununla birlikte, verimlilik konusunda süper endişeniz varsa, gist kodunu karşılaştırmak isteyebilirsiniz. Tüm fonksiyon çağrısının ne kadar ek yük getirdiğinden emin değilim.
SQL sorgusu üreten komut dosyaları veya ilk veya son öğeler için farklı bir işlem yapan herhangi bir şey için, gereksiz değişken denetimlerinin kullanılmasını önlemek çok daha hızlıdır (neredeyse iki kat daha hızlıdır).
Kabul edilen geçerli çözüm, döngü içinde bir döngü ve her_single_iteration yapılacak bir denetim kullanır, bunu yapmanın doğru (hızlı) yolu aşağıdaki gibidir:
$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
$some_item=$arr[$i];
$i++;
}
$last_item=$arr[$i];
$i++;
Küçük bir ev yapımı kriter aşağıdakileri gösterdi:
test1: model morg 100000 çalışır
zaman: 1869.3430423737 milisaniye
test2: 100000 model son çalışırsa
zaman: 3235.6359958649 milisaniye
Ve böylece çekin çok maliyetli olduğu ve tabii ki eklediğiniz daha değişken çeklerin daha da kötüleştiği açıktır;)
$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++;
çıktı:0: , 1: One, 2: ,
array()
yapılır {'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}
ama boş öğeler sayım ile yok sayılır, tanımlanmış "şeyler" sayısını sayıyor !! BOŞLUK KURULUŞU GELİYOR! Bu cevap lütfu hak ediyor, ama eğer @Morg. gitti, anlamsız. Muhtemelen tekrar kullanmayacak bir kişiye lütuf verecek! Eğer geri gelir ve cevabını iyileştirirse, ödülünü hak eder!
array_keys
işleve, olabilir bir dizi gibi davranın. Bkz benim "geliştirilmiş" cevabını .
$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'";
Anahtarlar ve Değerler ile bu da işe yarar:
foreach ($array as $key => $value) {
if ($value === end($array)) {
echo "LAST ELEMENT!";
}
}
Bir Boolean değişkeni kullanmak hala en güvenilir olanıdır, hatta ilk görünümünü kontrol etmek isteseniz bile $value
(bunu benim durumumda ve birçok durumda daha kullanışlı buldum) , şöyle:
$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';
}
}
Sonra yinelenecek bir değer yoksa geri dönecek !next( $array )
son bulmak nasıl .$value
true
next()
Ve ben bir sayaç kullanacaksam for
yerine bir döngü kullanmayı tercih ederim foreach
, şöyle:
$len = count( $array );
for ( $i = 0; $i < $len; $i++ ) {
$value = $array[$i];
if ($i === 0) {
// first
} elseif ( $i === $len - 1 ) {
// last
}
// …
$i++;
}
Aynı sorun olduğunda ben bu iş parçacığı rastladı. Sadece ilk eleman almak gerekir sonra bu aklıma kadar gelene kadar kodumu yeniden analiz.
$firstElement = true;
foreach ($reportData->result() as $row)
{
if($firstElement) { echo "first element"; $firstElement=false; }
// Other lines of codes here
}
Yukarıdaki kodlar harika ve eksiksiz ancak yalnızca ilk öğeye ihtiyacınız varsa bu kodu deneyebilirsiniz.
Hala gerekli olup olmadığından emin değilim. Ancak aşağıdaki çözüm yineleyicilerle çalışmalıdır ve gerektirmez 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;
}
}
}
Anonim bir işlevi de kullanabilirsiniz:
$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
}
});
Üç şeyden daha bahsetmek gerekir:
array_values
önce dizinizi oluşturmalısınız .$element
referans ( &$element
) ile geçmeniz gerekir .$indexOfLastElement
alarak bunları use
yapının içinde listelemeniz gerekir.Sayacı ve dizi uzunluğunu kullanabilirsiniz.
$ dizi = dizi (1,2,3,4); $ i = 0; $ len = sayım ($ dizi); foreach ($ dizi olarak $ item) { eğer ($ i === 0) { // ilk } else if ($ i === $ len - 1) { // son } //… ++ dolarım; }
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();
}
}
Kullanılması reset ($ dizi) ve uç ($ dizi)
<?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>";
}
}
Bunu dene:
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
vearray_pop
. Böyle bir şeyi uygulamak zorunda kalsaydım ortaya çıkan çözüm bu olsa da, şimdi Rok Kralj'ın cevabına sadık kalacağım .