Bir foreach döngü içinde ilk ve son yineleme nasıl belirlenir?

8 Cevap

Ben bir MySQL veritabanı üç tablo var.

  1. toplama
  2. kategori
  3. subkategori

Ben bir ağaç olarak görüntülemek için bu tablolardan veri almak için aşağıdaki fonksiyon kullanılır:

function create_menu($params) {
    //retrieve menu items 
    //get toplama 
    $toplama = get('xxtoplama') ;

    foreach($toplama as $c) {
        echo '<div class="parent" style="direction:rtl">';
        echo  '<img src="../images/dtree/minus.gif" align="absmiddle" class="parent_item" id="minus" />
               <img src="../images/dtree/base.gif" align="absmiddle" id="base">';
        echo $c['xtoplamaname'];

        //get categories 
        $cat = get_where('xxkategori' , array('xtoplamaid'=>$c['xtoplamaid'])) ; 

        foreach($cat as $item) {
            echo '<div class="node" >';
            echo  '<img src="../images/dtree/plus.gif" align="absmiddle" class="node_item" id="plus" />
                   <img src="../images/dtree/folder.gif" align="absmiddle" id="folder">';
            echo $item['xcatname'];

            $subcat = get_where('xxsubkategori' , array('xcatid'=>$item['xcatid']));

            foreach($subcat as $val) {  
                echo  '<div class="sub_node" style="display:none">' ; 
                echo  '<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">';
                echo $val['xsubcatname'].'</a>';
                echo '</div>';
            }

            echo '</div>';
        }

        echo '</div>';
    }
}
  1. Nasıl foreach döngüsünde ilk ve son yineleme belirleyebilirsiniz?
  2. Bir ağaç olarak görüntülenecek verileri almak için doğru yolu nedir?
  3. Ben bir ağaç gibi menüsünü görüntülemek için <div> etiketini kullanmak için standart olmadığını biliyorum. Ben iç içe <ul> s kullanmayı tercih. Ancak, her zaman IE <ul> ile ilgili sorunlar var. Ben farklı web tarayıcılarda çalışır <ul> etiketleri nasıl kullanılacağı hakkında bazı tavsiyeler veya kaynakları elde etmek istiyoruz.

8 Cevap

  1. Bir sayacı kullanabilirsiniz:

    $i = 0;
    $len = count($array);
    foreach ($array as $item) {
        if ($i == 0) {
            // first
        } else if ($i == $len - 1) {
            // last
        }
        // …
        $i++;
    }
    
  2. Sizin yöntem her koleksiyonu, kategori ve alt kategori için bir veritabanı sorgusu gerektirir. 10 koleksiyonları, 100 kategori ve 1000 alt varsa Yani, en azından 1110 veritabanı sorguları olacaktır.

    Sen (tablo katıldı bakınız) ya da masa başına en az bir sorgu sadece tek bir sorgu ile bunu denemelisiniz.

  3. Uygun bir el listesi daima div çorba daha iyidir. Yani ul ve li kullanmayı deneyin.

Diziniz eşsiz dizi değerlere sahipse, o zaman ilk ve son belirleyici unsur Önemsiz:

foreach($array as $element) {
    if ($element === reset($array))
        echo 'FIRST ELEMENT!';

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

Ilk ve son elemanları, aksi takdirde yanlış pozitif olsun, sadece bir kez bir dizide görünen ise bu çalışır. Bu nedenle, anahtarları (onlar emin için benzersiz) karşılaştırmak gerekir. Eğer performansı hakkında endişeleriniz varsa, bu, aynı zamanda tercih edilen bir yöntemdir.

foreach($array as $key => $element) {
    reset($array);
    if ($key === key($array))
        echo 'FIRST ELEMENT!';

    end($array);
    if ($key === key($array))
        echo 'LAST ELEMENT!';
}

Eğer sık ​​sık bu yöntemi kullanırsanız Update:, bir fonksiyon yazmak gerekir:

function last(&$array, $key) {
    end($array);
    return $key === key($array);
}

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

You could remove the first and last elements off the array and process them separately.
Like this:

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

Yerine inline etiketleri CSS tüm biçimlendirme Çıkarma kodunuzu geliştirmek ve yükleme süresini hızlandırmak olacaktır.

You could also avoid mixing HTML with php logic whenever possible.
Your page could be made a lot more readable and maintainable by separating things like this:

<?php
function create_menu($params) {
  //retirive 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
}
?>

Yukarıda ve özel dizinleri kullanarak değil küstah bir daha basitleştirilmiş versiyonu ...

$len = count($array);
foreach ($array as $index => $item) {
    if ($index == 0) {
        // first
    } else if ($index == $len - 1) {
        // last
    }
}

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

Ve bu kontrolü bir çok maliyeti, ve tabii ki eklemek daha değişken kontrolleri daha da kötü olur ki, böylece oldukça açık ;)

1: Neden basit bir for deyimini kullanmak değil mi? Gerçek bir dizi kullanarak konum ve bir Iterator kolayca sayaç değişken unsurların tam sayısından 0 veya birden daha az olup olmadığını kontrol olamazdı varsayarsak. Bence bu en temiz ve anlaşılır bir çözümdür ...

$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: Sen ağaç yapısını saklamak için Nested Sets kullanmayı düşünmelisiniz. Ayrıca sen özyinelemeli fonksiyonlarını kullanarak her şeyi iyileştirebilir.

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

}

Bu deneyin:

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