PHP bir foreach döngü kullanarak sırasında bir dizinin son elemanı bulmak

23 Cevap php

Ben bazı parametreleri kullanarak bir SQL sorgu yaratıcısı yazıyorum. Java'da, sadece dizi uzunluğu ile geçerli dizi konumunu kontrol ederek for döngüsü içinde bir dizinin son elemanı tespit etmek çok kolay.

for(int i=0; i< arr.length;i++){

     boolean isLastElem = i== (arr.length -1) ? true : false;        

}

PHP onlar diziler erişmek için tamsayı olmayan endeksler var. Yani bir foreach döngü kullanarak bir dizi üzerinde yineleme gerekir. Eğer (sorgu inşa ederken benim durumumda ekleme ve / veya parametre için) bazı karar almak gerektiğinde, bu sorunlu olur.

Ben bunu bazı standart yolu olmalı eminim.

Nasıl PHP bu çözmek mi?

23 Cevap

Eğer böyle bir şey istediğiniz gibi geliyor:

$numItems = count($arr);
$i = 0;
foreach($arr as $key=>$value) {
  if(++$i === $numItems) {
    echo "last index!";
  }
}    

Söyleniyor, sen-yok-için ne php foreach kullanarak bir "dizi" tekrarlatacak.

Sen end(array_keys($array)) ile geçerli anahtarın karşılaştırın kullanarak dizinin son anahtarının değerini alabilir:

$last_key = end(array_keys($array));
foreach ($array as $key => $value) {
    if ($key == $last_key) {
        // last element
    } else {
        // not last element
    }
}

neden bu kadar karmaşık?

foreach($input as $key => $value) {
    $ret .= "$value";
    if (next($input)==true) $ret .= ",";
}

Bu sonuncusu hariç her değerin arkasında, bir katacak!

$toEnd = count($arr);
foreach($arr as $key=>$value) {
  if (0 === --$toEnd) {
    echo "last index! $value";
  }
}

Hala diğer döngü kodunu çalıştırmak, ya da en iyi yolu muhtemelen bu

foreach($arr as $key=>$value) {
  //something
}
echo "last index! $key => $value";

Orada birçok cevap zaten, ama bu standart bir şekilde talep edilmiştir, özellikle de Yineleyicilerde içine bakmak için değer:

$arr = range(1, 3);

$it = new CachingIterator(new ArrayIterator($arr));
foreach($it as $key => $value)
{
  if (!$it->hasNext()) echo 'Last:';
  echo $value, "\n";
}

Siz de, diğer durumlarda daha esnek çalışır bir şeyler bulabilirsiniz.

Eğer bir değişken depolanan dizi var varsayarsak ...

foreach($array as $key=>$value) 
{ 
    echo $value;
    if($key != count($array)-1) { echo ", "; }
}

Eğer ilk veya son ve dizide birden fazla unsur var sadece, ben şu çözümü tercih ya dışında her element için bir şeyler yapmak gerekir.

Orada birçok çözümleri üzerinde olan ve benim aylar önce / bir yıl yayınlanmıştır biliyorum, ama bu kendi başına oldukça şık hissediyorum şeydir. Daha az yük için izin verebilir bir sayısal "i = (saymak-1)" çek, aksine onay her döngü de bir mantıksal kontrol edilir.

Döngü yapısı garip hissedebilirsiniz, ancak (başlangıç) thead ve sipariş için karşılaştırabilirsiniz, tfoot (uç), HTML tablo etiketleri tbody (akım).

$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;
}

, Ilk çocuk: Bir Sırasız listesi (ul) bir border-bottom to every element except the last eklemek istiyorsanız Örneğin, web geliştirme açısından, o zaman yerine bir border-top to every element except the first (CSS ekleyebilirsiniz son çocuk IE7 tarafından desteklenmez): oysa IE7 + ve Firefox / Webkit tarafından desteklenen, bu mantığı destekliyor.

Siz de her iç içe döngü için $ ilk değişkeni yeniden ve şeyler (sonları / istisnalar sorunlarına neden olmayacak şekilde) her döngü ilk yinelemenin ilk sürecinde $ ilk yanlış yapar beri sadece iyi çalışır özgür hissedebilirsiniz .

$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;

Örnek çıktı:

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)

Hala ilişkilendirilebilir dizilerle bu yöntemi kullanabilirsiniz:

$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;
}

Diziniz eşsiz dizi değerleri varsa Yani, o son yineleme belirlenmesi Önemsiz:

foreach($array as $element) {
    if ($element === end($array))
        echo 'LAST ELEMENT!';
}

Gördüğünüz gibi, son elemanı aksi takdirde yanlış alarm olsun, sadece bir kez dizide görünen ise, bu işleri. Öyle değil, sen (kesin benzersiz) anahtarları karşılaştırmak gerekir.

foreach($array as $key => $element) {
    end($array);
    if ($key === key($array))
        echo 'LAST ELEMENT!';
}

Ayrıca bu durumda oldukça önemlidir sıkı coparision operatörü, unutmayın.

Eğer) (sayımını yapabilirsiniz.

for ($i=0;$i<count(arr);$i++){
    $i == count(arr)-1 ? true : false;
}

SADECE son eleman arıyorsanız ya, sen sonuna () kullanabilirsiniz.

end(arr);

Sadece son öğeyi döndürür.

bu çıkıyor gibi ve, tamsayılar tarafından index php dizileri CAN. Bu mükemmel mutlu

arr[1];

It sounds like you want something like this:

$array = array(
    'First',
    'Second',
    'Third',
    'Last'
);

foreach($array as $key => $value)
{
    if(end($array) === $value)
    {
       echo "last index!" . $value;
    }
}

Ben bu "XY sorunu" kökünde OP sadece implode() function istediğini güçlü bir his var.

EOF dizi bulma niyeti sadece tutkal için olduğu gibi. Aşağıdaki taktik tanıttı olsun. Sen EOF gerektirmez gerekir:

$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

Ben oldukça düzgün olduğunu hissediyorum ben biraz aşağıdaki gibi. Hepimizin elemanları arasındaki ayırıcılar ile bir dize oluştururken varsayalım: örn a, b, c

$first = true;
foreach ( $items as $item ) {
    $str = ($first)?$first=false:", ".$item;
}

İşte bunu yapabileceği başka bir yolu:

$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);
    }
}

Seni anlıyorum, o zaman ihtiyacınız olan tüm dizi ters ve bir pop komutuyla son öğeyi almak için:

   $rev_array = array_reverse($array);

   echo array_pop($rev_array);

Ayrıca INSERT burada gösterilen ... sorgunuzu yapmak için bu deneyebilirsiniz

<?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;
?>

Siz de böyle bir şey yapabilirsiniz:

end( $elements );
$endKey = key($elements);
foreach ($elements as $key => $value)
{
     if ($key == $endKey) // -- this is the last item
     {
          // do something
     }

     // more code
}

SQL sorgu üreten komut, ya da ilk veya son elemanları için farklı bir eylem yok bir şey için, çok daha hızlı (neredeyse iki kat daha hızlı) gereksiz değişken kontrolleri kullanarak kaçınmaktır.

Geçerli kabul edilen çözüm every_single_iteration yapılacaktır döngü içinde bir döngü ve bir çek kullanır, bunu yapmak için doğru (hızlı) yolu şudur:

$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
    $some_item=$arr[$i];
    $i++;
}
$last_item=$arr[$i];
$i++;

Biraz ev yapımı kriter aşağıdaki gösterdi:

test1: modeli morgda 100000 çalışır

zaman: 1.869,3430423737 milisaniye

test2: modelin 100000 çalışır eğer son

zaman: 3235,6359958649 milisaniye

Gitmek için başka bir yolu önceki döngü döngü sonucunu hatırlamak ve sonuç olarak bu kullanmak için:

    $result = $where = "";
    foreach ($conditions as $col => $val) {
        $result = $where .= $this->getAdapter()->quoteInto($col.' = ?', $val);
        $where .=  " AND ";
    }
    return $this->delete($result);

Ben şahsen html ile kolay bir kullanım sağlamak inşaatı bu tür kullanımı < ul> ve < li> elementler: sadece başka bir özelliği için eşitlik değiştirmek ...

Dizi yanlış öğeleri ama yanlış mantıksal içine dökme tüm diğerleri öğeleri içeriyor olamaz.

$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;
}

Sen dirctly son endeksi ile alabilirsiniz:

$numItems = count($arr);

echo $arr[$numItems-1];

Ben bir dize değerleri diziden bir dize derleme ortak bir amaç için, ben kullanmak genel bir çözüm var. Ben yaptığım sonuna kadar alışılmadık bir dize eklemek ve sonra dışarı değiştirin.

Function to return a string from an array, separated, with no trailing separator:

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;
}

Özel, ama çalışıyor bir şey :)