วิธีการกำหนดซ้ำครั้งแรกและครั้งสุดท้ายในลูป foreach?


494

คำถามง่าย ๆ ฉันมีforeachวงวนในรหัสของฉัน:

foreach($array as $element) {
    //code
}

ในวงนี้ฉันต้องการที่จะตอบสนองที่แตกต่างกันเมื่อเราอยู่ในการทำซ้ำครั้งแรกหรือครั้งสุดท้าย

ทำอย่างไร

คำตอบ:


426

คุณสามารถใช้เคาน์เตอร์:

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

24
ฉันไม่คิดว่า downvoting ควรจะเกิดขึ้นที่นี่เช่นนี้เป็นยังทำงานได้อย่างถูกต้องและยังคงไม่ให้ขยะการใช้และarray_shift array_popแม้ว่านี่จะเป็นวิธีแก้ปัญหาที่ฉันเกิดขึ้นถ้าฉันต้องทำสิ่งนั้นฉันจะทำตามคำตอบของ Rok Kralj ในตอนนี้
ร่มรื่น

15
ถ้าฉันต้องการตัวนับฉันก็ชอบใช้ FOR loop แทน FOREACH
rkawano

10
ถ้าคุณใช้$i = 1คุณไม่ต้องกังวลเกี่ยวกับการใช้งานเพียงแค่$len - 1 $len
aksu

2
@Twan จุดที่ 3 เป็นอย่างไร หรือเกี่ยวข้องกับคำถามนี้เนื่องจากเกี่ยวข้องกับ HTML หรือไม่ นี่เป็นคำถาม PHP อย่างชัดเจน ... และเมื่อพูดถึงความหมายของมาร์คอัปมันเป็นข้อเท็จจริงที่ลึกซึ้งยิ่งกว่า "blahblah ที่เหมาะสมดีกว่า blahblah เสมอ (นี่ไม่ใช่ความเห็นของฉันมันเป็นความจริงแท้)"
Deji

1
@rkawano แต่คุณไม่สามารถรับคีย์ชื่อถ้าคุณใช้สำหรับการวนรอบ
Fahmi

1015

หากคุณต้องการโซลูชันที่ไม่ต้องการการเริ่มต้นของตัวนับนอกลูปฉันขอเสนอการเปรียบเทียบคีย์การวนซ้ำปัจจุบันกับฟังก์ชันที่บอกให้คุณทราบถึงคีย์สุดท้าย / แรกของอาร์เรย์

สิ่งนี้จะมีประสิทธิภาพมากขึ้น (และสามารถอ่านได้มากขึ้น) ด้วย PHP 7.3 ที่กำลังจะมาถึง

โซลูชันสำหรับ PHP 7.3 และสูงกว่า:

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

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

โซลูชันสำหรับ PHP ทุกเวอร์ชัน:

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

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

44
คำตอบที่ยอดเยี่ยม! สะอาดกว่าการใช้อาร์เรย์จำนวนมาก
พอล J

14
นี่จะทำให้เกิดฟองขึ้นไปด้านบนเพราะมันเป็นคำตอบที่ถูกต้อง ข้อดีอีกประการของฟังก์ชั่นเหล่านี้มากกว่าการใช้ array_shift และ array_pop ก็คืออาร์เรย์นั้นยังคงอยู่เหมือนเดิมในกรณีที่จำเป็นต้องใช้ในภายหลัง +1 สำหรับการแบ่งปันความรู้เพียงเพื่อประโยชน์ของมัน
Awemo

13
นี่เป็นวิธีที่ดีที่สุดถ้าคุณต้องการรักษาความสะอาดของรหัส ฉันกำลังจะถอนรากถอนโคน แต่ตอนนี้ฉันไม่มั่นใจว่าค่าใช้จ่ายในการทำงานของวิธีอาร์เรย์เหล่านั้นคุ้มค่า ถ้าเราแค่พูดถึงองค์ประกอบสุดท้ายนั่นก็คือend()+ key()การวนซ้ำของลูป - ถ้ามันทั้งคู่นั่นคือ 4 วิธีที่ถูกเรียกทุกครั้ง จริงอยู่ที่การดำเนินการเหล่านี้มีน้ำหนักเบามากและอาจเป็นเพียงการค้นหาตัวชี้ แต่จากนั้นเอกสารจะดำเนินการเพื่อระบุreset()และend() แก้ไขตัวชี้ภายในของอาร์เรย์ - ดังนั้นจะเร็วกว่าตัวนับหรือไม่ อาจจะไม่
pospi

19
ฉันไม่คิดว่าคุณควรออกรีเซ็ต ($ array) ภายใน foreach จากเอกสารอย่างเป็นทางการ (www.php.net/foreach): "เมื่อ foreach อาศัยตัวชี้อาร์เรย์ภายในการเปลี่ยนภายในลูปอาจทำให้เกิดพฤติกรรมที่ไม่คาดคิด" และการรีเซ็ตทำได้อย่างแม่นยำ (www.php.net/reset): "ตั้งค่าตัวชี้ภายในของอาร์เรย์ให้เป็นองค์ประกอบแรก"
GonçaloQueirós

11
@ GonçaloQueirós: ใช้งานได้ Foreach ทำงานกับสำเนาของอาร์เรย์ อย่างไรก็ตามหากคุณยังมีความกังวลคุณสามารถย้ายreset()สายก่อนหน้า foreach และแคชผลลัพธ์$firstได้
Rok Kralj

121

ในการค้นหารายการสุดท้ายฉันพบว่าโค้ดชิ้นนี้ใช้ได้ทุกครั้ง:

foreach( $items as $item ) {
    if( !next( $items ) ) {
        echo 'Last Item';
    }
}

2
มี upvotes น้อยเกินไปมีข้อ จำกัด ในการใช้หรือไม่
Kevin Kuyl


2
@Kevin Kuyl - ตามที่ Pang กล่าวไว้ข้างต้นหากอาร์เรย์มีรายการที่ PHP ประเมินว่าเป็นเท็จ (เช่น 0, "", null) วิธีนี้จะมีผลลัพธ์ที่ไม่คาดคิด ฉันแก้ไขรหัสเพื่อใช้ ===
Eric Kigathi

4
นี้ส่วนใหญ่จะเป็นที่น่ากลัวมาก [true,true,false,true]แต่ที่จะชี้แจงในการแก้ไขปัญหาที่คนอื่นจะชี้ให้เห็นว่ามันอย่างสม่ำเสมอจะล้มเหลวกับอาร์เรย์เช่น falseแต่ส่วนตัวผมจะใช้ทุกที่ทุกเวลานี้ฉันกำลังจัดการกับอาร์เรย์ที่ไม่ได้มีบูล
billynoah

4
next()ไม่ควรใช้ภายในลูป foreach มันเลอะตัวชี้อาร์เรย์ภายใน ตรวจสอบเอกสารสำหรับข้อมูลเพิ่มเติม
Drazzah

89

เวอร์ชันด้านบนที่ง่ายขึ้นและสันนิษฐานว่าคุณไม่ได้ใช้ดัชนีที่กำหนดเอง ...

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

รุ่นที่ 2 - เพราะฉันมาเกลียดการใช้สิ่งอื่นเว้นแต่จำเป็น

$len = count($array);
foreach ($array as $index => $item) {
    if ($index == 0) {
        // first
        // do something
        continue;
    }

    if ($index == $len - 1) {
        // last
        // do something
        continue;
    }
}

8
สิ่งนี้ใช้ได้กับวัตถุด้วย โซลูชันอื่น ๆ ใช้งานได้กับอาร์เรย์เท่านั้น
Lamy

1
นี่เป็นคำตอบที่ดีที่สุดสำหรับฉัน แต่ควรย่อตัวไม่มีจุดประกาศความยาวนอกลูป foreach: if ($ index == count ($ array) -1) {... }
Andrew

2
@ แสดงวิธีที่คุณให้นับองค์ประกอบของอาร์เรย์ทุกครั้งที่มีการวนซ้ำ
pcarvalho

1
@ peteroak ใช่จริง ๆ แล้วมันจะเจ็บประสิทธิภาพการทำงานและขึ้นอยู่กับการนับของคุณหรือจำนวนลูปอาจมีความสำคัญ ดังนั้นไม่ต้องสนใจความคิดเห็นของฉัน: D
Andrew

4
@peteroak @Andrew จำนวนรวมขององค์ประกอบในอาร์เรย์ถูกเก็บไว้เป็นทรัพย์สินภายในจึงมีจะไม่ฮิตการใด ๆ if ($index == count($array) - 1)โดยการทำ ดูที่นี่
GreeKatrina

36

คุณสามารถลบองค์ประกอบแรกและสุดท้ายออกจากอาร์เรย์และดำเนินการแยกต่างหาก

แบบนี้:

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

การลบการจัดรูปแบบทั้งหมดเป็น CSS แทนที่จะเป็นแท็กแบบอินไลน์จะช่วยปรับปรุงรหัสของคุณและเพิ่มความเร็วในการโหลด

คุณสามารถหลีกเลี่ยงการผสม HTML กับตรรกะของ php เมื่อทำได้

หน้าของคุณสามารถทำให้สามารถอ่านและบำรุงรักษาได้มากขึ้นโดยแยกสิ่งต่าง ๆ ดังนี้:

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

20

ความพยายามที่จะหาคนแรกจะเป็น:

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

3
โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายวิธีการทำงานของรหัสของคุณและวิธีแก้ปัญหาของ OP ผู้โพสต์จำนวนมากเป็นมือใหม่และจะไม่เข้าใจรหัสที่คุณโพสต์
ฉันตื่นตระหนกกับมนุษย์ต่างดาว

4
คำตอบนี้ไม่ได้บอกวิธีการตรวจสอบว่าคุณอยู่ในการทำซ้ำครั้งล่าสุดของวง อย่างไรก็ตามเป็นความพยายามที่ถูกต้องในคำตอบและไม่ควรตั้งค่าสถานะเป็นไม่ใช่คำตอบ หากคุณไม่ชอบคุณควรลงคะแนนอย่าตั้งค่าสถานะ
ArtOfWarfare

ชัดเจนในการทำซ้ำครั้งแรกเขาจะเข้าสู่เงื่อนไขแรกแล้วเปลี่ยนเป็นค่าเท็จและด้วยวิธีนี้มันจะเข้าสู่การทำซ้ำครั้งแรกเพียงครั้งเดียว
Mohamed23gharbi

20

แค่ใช้งานได้!

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

ขอบคุณ @billynoah สำหรับการแยกแยะปัญหาสุดท้าย


3
พิเศษสุด! if ($key === $lastkey)ฉันเพียงจะชี้แจง
Krzysztof Przygoda

2
ไม่ควรเป็นเช่นนี้ if ($lastkey === $key)?
Kinetic

1
ฉันได้รับ:PHP Warning: key() expects parameter 1 to be array, integer given in php shell code on line 1
billynoah

1
@Sydwell - อ่านข้อผิดพลาด จะได้รับจำนวนเต็มไม่ key() " ส่งคืนค่าขององค์ประกอบสุดท้าย " และคาดว่าอาร์เรย์จะเป็นอินพุต end()end()key()
billynoah


11

1: ทำไมไม่ใช้forคำสั่งง่าย ๆ? สมมติว่าคุณกำลังใช้อาร์เรย์จริงและไม่ใช่Iteratorคุณสามารถตรวจสอบได้ง่ายว่าตัวแปรตัวนับเป็น 0 หรือน้อยกว่าจำนวนองค์ประกอบทั้งหมด ในความคิดของฉันนี่เป็นทางออกที่สะอาดและเข้าใจง่ายที่สุด ...

$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: คุณควรพิจารณาใช้ชุดที่ซ้อนกันเพื่อจัดเก็บโครงสร้างต้นไม้ของคุณ นอกจากนี้คุณสามารถปรับปรุงทุกสิ่งโดยใช้ฟังก์ชั่นวนซ้ำ


หากคุณกำลังจะใช้forคุณสามารถวนจาก1ไปn-1และนำifออกจากร่างกาย ไม่มีจุดตรวจสอบพวกเขาซ้ำ ๆ
mpen

9

คำตอบที่ดีที่สุด:

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

}

2
สิ่งนี้จะล้มเหลวเมื่อคุณมีองค์ประกอบเดียวในอาร์เรย์
Memochipan

4
มันรวดเร็วและง่ายดายตราบใดที่คุณสามารถมั่นใจได้ว่ามีมากกว่าหนึ่ง lement ในอาร์เรย์ (ตามที่ Memochipan กล่าว) ดังนั้นจึงไม่ใช่ทางออกที่ปลอดภัยสำหรับฉัน - ไม่ใช่ 'คำตอบที่ดีที่สุด'
Seika85

5
แต่ละ () จะเลิกเป็นของ PHP 7.2.0 โปรดดูphp.net/manual/en/function.each.php
Flow

8

คำตอบที่มีประสิทธิภาพมากที่สุดจาก @morg ต่างจากforeachใช้งานได้กับอาร์เรย์ที่เหมาะสมเท่านั้นไม่ใช้แฮชวัตถุแผนที่ คำตอบนี้หลีกเลี่ยงค่าใช้จ่ายของคำสั่งแบบมีเงื่อนไขสำหรับการวนซ้ำทุกครั้งของลูปในคำตอบส่วนใหญ่ (รวมถึงคำตอบที่ยอมรับ) โดยเฉพาะการจัดการองค์ประกอบแรกและครั้งสุดท้ายและวนลูปกับองค์ประกอบกลาง

array_keysฟังก์ชั่นสามารถนำมาใช้เพื่อให้การทำงานมีประสิทธิภาพเช่นคำตอบ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++;

ฉันยังไม่ได้ทำการเปรียบเทียบในเรื่องนี้ แต่ไม่มีการเพิ่มตรรกะในลูปซึ่งเป็นผลการดำเนินงานที่ยิ่งใหญ่ที่สุดดังนั้นฉันสงสัยว่ามาตรฐานที่ให้มาพร้อมกับคำตอบที่มีประสิทธิภาพนั้นค่อนข้างใกล้เคียง

หากคุณต้องการที่จะfunctionalizeชนิดของสิ่งนี้ผมได้นำการแกว่งที่ดังกล่าวฟังก์ชั่น iterateList ที่นี่ แม้ว่าคุณอาจต้องการเกณฑ์มาตรฐานส่วนสำคัญถ้าคุณกังวลอย่างมากเกี่ยวกับประสิทธิภาพ ฉันไม่แน่ใจว่าค่าใช้จ่ายทั้งหมดที่เรียกใช้ฟังก์ชั่นคือเท่าใด


6

สำหรับสคริปต์ที่สร้างคิวรี SQL หรือสิ่งใดก็ตามที่ทำการกระทำที่แตกต่างกันสำหรับองค์ประกอบแรกหรือองค์ประกอบสุดท้ายจะเร็วกว่ามาก (เกือบสองเท่าเร็ว) เพื่อหลีกเลี่ยงการใช้การตรวจสอบตัวแปรที่ไม่จำเป็น

โซลูชันที่ยอมรับในปัจจุบันใช้การวนซ้ำและการตรวจสอบภายในลูปที่จะทำ 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++;

มาตรฐานโฮมเมดเล็ก ๆ น้อย ๆ แสดงให้เห็นต่อไปนี้:

test1: 100,000 รุ่นของ morg

เวลา: 1869.3430423737 มิลลิวินาที

test2: 100,000 รุ่นที่รันล่าสุด

เวลา: 3235.6359958649 มิลลิวินาที

และมันค่อนข้างชัดเจนว่าการตรวจสอบมีค่าใช้จ่ายสูงและแน่นอนว่ายิ่งแย่ลงยิ่งคุณเพิ่มการตรวจสอบตัวแปรมากขึ้น)


รหัสของคุณใช้งานได้ก็ต่อเมื่อคุณต้องแน่ใจว่าจะต้องมีคีย์จำนวนเต็มเพิ่มขึ้น $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++;จะส่งออก:0: , 1: One, 2: ,
Seika85

การหล่อแผนที่แฮชไปยังอาเรย์นั้นเป็นพฤติกรรมที่ไม่สามารถระบุได้ "Object" ที่array()ทำขึ้น{'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}แต่องค์ประกอบที่ว่างเปล่าจะถูกละเว้นด้วยการนับคุณกำลังนับจำนวนสิ่งที่กำหนดไว้ "!! SACRIFICE เข้ามาจำนวนมาก! คำตอบนี้สมควรได้รับความโปรดปราน แต่ถ้า @Morg หายไปมันไร้ประโยชน์ ฉันจะให้รางวัลกับคนที่อาจจะไม่ได้ใช้อีกแล้ว! ถ้าเขากลับมาและปรับปรุงคำตอบของเขาเขาสมควรได้รับรางวัล!
mjz19910

ในฐานะที่เป็น @ mjz19910 โน้ตแฮชแม็พและอาร์เรย์จะไม่สามารถใช้แทนกันได้ อย่างไรก็ตามคุณสามารถรับคุณสมบัติของแฮชได้ด้วยarray_keysฟังก์ชั่นซึ่งคุณสามารถปฏิบัติได้เหมือนอาเรย์ ดู"ดีขึ้น" ฉันตอบ
TheMadDeveloper

นั่นคือสิ่งที่ฉันใช้สำหรับการสืบค้น:$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'";
Rovshan Mamedov

5

ด้วยคีย์และค่านี้ใช้งานได้เช่นกัน:

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

2
วิธีนี้คุณจะเปรียบเทียบค่าและไม่ทำงานหากอาร์เรย์มีองค์ประกอบสองอย่างเดียวกัน
Krzysztof Przygoda

5

การใช้ตัวแปรบูลีนยังคงเชื่อถือได้มากที่สุดแม้ว่าคุณต้องการตรวจสอบการปรากฏตัวครั้งแรกของ$value (ฉันพบว่ามันมีประโยชน์มากขึ้นในสถานการณ์ของฉันและในหลาย ๆ สถานการณ์)เช่นนี้:

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

จากนั้น!next( $array )จะหาวิธีสุดท้าย$valueที่จะกลับมาtrueหากไม่มีnext()มูลค่าให้กับสำทับ

และฉันชอบที่จะใช้forวงวนแทนforeachถ้าฉันจะใช้ตัวนับแบบนี้:

$len = count( $array );
for ( $i = 0; $i < $len; $i++ ) {
    $value = $array[$i];
    if ($i === 0) {
        // first
    } elseif ( $i === $len - 1 ) {
        // last
    }
    // …
    $i++;
}

4

ฉันเจอกระทู้นี้เมื่อฉันมีปัญหาเดียวกัน ฉันแค่ต้องได้รับองค์ประกอบแรกจากนั้นฉันวิเคราะห์รหัสของฉันอีกครั้งจนกระทั่งสิ่งนี้มาถึงใจของฉัน

$firstElement = true;

foreach ($reportData->result() as $row) 
{
       if($firstElement) { echo "first element"; $firstElement=false; }
       // Other lines of codes here
}

รหัสข้างต้นนั้นยอดเยี่ยมและสมบูรณ์ แต่ถ้าคุณต้องการเพียงแค่องค์ประกอบแรกคุณสามารถลองใช้รหัสนี้ได้


2

ไม่แน่ใจว่ายังจำเป็นอยู่หรือไม่ แต่การแก้ปัญหาต่อไปนี้ควรทำงานร่วมกับ iterators 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;
        }
    }
}

0

คุณสามารถใช้ฟังก์ชันที่ไม่ระบุชื่อเช่นกัน:

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

ควรพูดถึงสามสิ่งเพิ่มเติม:

  • หากอาร์เรย์ของคุณไม่ได้จัดทำดัชนีอย่างเคร่งครัด (ตัวเลข) คุณต้องไพพ์อาร์เรย์ของคุณarray_valuesก่อน
  • หากคุณต้องการแก้ไข$elementคุณจะต้องผ่านการอ้างอิง ( &$element)
  • ตัวแปรใด ๆ จากภายนอกฟังก์ชั่นที่ไม่ระบุชื่อที่คุณต้องการภายในคุณจะต้องแสดงรายการถัดจาก$indexOfLastElementภายในuseโครงสร้างอีกครั้งโดยอ้างอิงถ้าจำเป็น


0
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();
   }
}

0

การใช้รีเซ็ต ($ array)และสิ้นสุด ($ array)

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

    }

repl.it สาธิต


-2

ลองสิ่งนี้:

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);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.