วิธีการลบวัตถุจากอาร์เรย์ภายในวงวนก่อน?


140

ฉันวนซ้ำวัตถุต่างๆและต้องการลบวัตถุใดวัตถุหนึ่งโดยพิจารณาจากคุณสมบัติ 'id' แต่รหัสของฉันไม่ทำงาน

foreach($array as $element) {
    foreach($element as $key => $value) {
        if($key == 'id' && $value == 'searched_value'){
            //delete this particular object from the $array
            unset($element);//this doesn't work
            unset($array,$element);//neither does this
        } 
    }
}

ข้อเสนอแนะใด ๆ ขอบคุณ


คำตอบ:


233
foreach($array as $elementKey => $element) {
    foreach($element as $valueKey => $value) {
        if($valueKey == 'id' && $value == 'searched_value'){
            //delete this particular object from the $array
            unset($array[$elementKey]);
        } 
    }
}

62
จะปลอดภัยไหมที่จะลบองค์ประกอบของอาเรย์ภายในลูป foreach ของอาเรย์เดียวกัน
Olivier Pons

25
@Oliver: โดยปกติจะสร้างพฤติกรรมที่ไม่คาดคิด แต่คุณสามารถทำได้อย่างปลอดภัยด้วย foreach บน php ให้อ่านที่นี่สำหรับการทดสอบ: php.net/manual/en/control-structures.foreach.php#88578
pangon

1
@Paritosh ฉันรู้ว่าคุณโพสต์สิ่งนี้มานานแล้ว แต่เป็นเพราะ PHP ใช้อาเรย์แบบเชื่อมโยง ดังนั้นคุณมีดัชนีที่ถูกลบ: และมันจะถูกเข้ารหัสไปยัง JSON เป็นวัตถุ เหมาะสมเนื่องจากอาร์เรย์ที่เชื่อมโยงกันเป็น "พจนานุกรม" อาจช่วยคนที่กำลังมาด้วย
Ryan O'Donnell

1
คุณต้องการที่จะทำอย่างที่สองสำหรับแต่ละคน? คุณไม่สามารถค้นหาคุณสมบัติ 'id' ที่ต้องการของวัตถุได้หรือไม่ ตรวจสอบอุปกรณ์ประกอบฉากอื่น ๆ ทั้งหมดทำไม
htafoya

3
@hafafoya ไม่คุณทำได้แค่if(isset($element['id']) && $element['id'] == 'searched_value') { unset($array[$elementKey]); }คิดในเวลาที่ฉันเพิ่งคัดลอกและแก้ไขรหัสของเขาเพื่อแสดงวิธีการunsetอย่างถูกต้อง
prodigitalson

2

ดูเหมือนว่าไวยากรณ์ของคุณสำหรับการตั้งค่าไม่ถูกต้องและการไม่มีการทำดัชนีใหม่อาจทำให้เกิดปัญหาในอนาคต ดู: ส่วนบนอาร์เรย์ PHP

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


2

คุณยังสามารถใช้การอ้างอิงกับforeachค่า:

foreach($array as $elementKey => &$element) {
    // $element is the same than &$array[$elementKey]
    if (isset($element['id']) and $element['id'] == 'searched_value') {
        unset($element);
    }
}

9
$ องค์ประกอบ (ใช้ในและนอก foreach) เป็นเพียงการอ้างอิงถึงแต่ละองค์ประกอบในอาร์เรย์ unset ($ องค์ประกอบ) จะทำลายการอ้างอิงเท่านั้นมันไม่ทำลายองค์ประกอบที่อ้างอิงจากอาร์เรย์
นิโคลัส

3
@Dev_NIX $element = nullจะไม่ทำงานความยาวของ$arrayคงเหมือนเดิมมันจะมีค่าเป็นโมฆะ
Nico Westerdale

1

สิ่งนี้ควรทำเคล็ดลับ .....

reset($array);
while (list($elementKey, $element) = each($array)) {
    while (list($key, $value2) = each($element)) {
        if($key == 'id' && $value == 'searched_value') {
            unset($array[$elementKey]);
        }
    }
}

1

ระวังด้วยคำตอบหลัก

กับ

[['id'=>1,'cat'=>'vip']
,['id'=>2,'cat'=>'vip']
,['id'=>3,'cat'=>'normal']

และเรียกใช้ฟังก์ชัน

foreach($array as $elementKey => $element) {
    foreach($element as $valueKey => $value) {
        if($valueKey == 'cat' && $value == 'vip'){
            //delete this particular object from the $array
            unset($array[$elementKey]);
        } 
    }
}

มันกลับมา

[2=>['id'=>3,'cat'=>'normal']

แทน

[0=>['id'=>3,'cat'=>'normal']

มันเป็นเพราะการตั้งค่าไม่ได้จัดทำดัชนีอาร์เรย์อีกครั้ง

มันทำดัชนีใหม่ (ถ้าเราต้องการ)

$result=[];
foreach($array as $elementKey => $element) {
    foreach($element as $valueKey => $value) {
        $found=false;
        if($valueKey === 'cat' && $value === 'vip'){
            $found=true;
            $break;
        } 
        if(!$found) {
           $result[]=$element;
        }
    }
}

0

ฉันไม่ได้เป็นโปรแกรมเมอร์ php มากนัก แต่ฉันสามารถพูดได้ว่าใน C # คุณไม่สามารถแก้ไขอาร์เรย์ในขณะที่วนซ้ำมันได้ คุณอาจต้องการลองใช้ลูป foreach ของคุณเพื่อระบุดัชนีขององค์ประกอบหรือองค์ประกอบที่จะลบจากนั้นลบองค์ประกอบหลังจากลูป


14
ในขณะที่เป็นการปฏิบัติที่ไม่ดีในภาษาส่วนใหญ่อาร์เรย์ใน PHP นั้นเป็นอาร์เรย์ที่เชื่อมโยงกันซึ่งสามารถทำซ้ำตามลำดับ การลบองค์ประกอบก่อนหน้าจะไม่เปลี่ยนคีย์ขององค์ประกอบที่ตามมา
Ignacio Vazquez-Abrams

22
ที่จริงแล้วมันได้รับอนุญาตเพราะอาร์เรย์ที่ foreach ใช้ภายในนั้นเป็นสำเนาของอาร์เรย์เดิม ด้วยวิธีดังกล่าวการปรับเปลี่ยนอาร์เรย์ดั้งเดิมจึงมีความปลอดภัยอย่างสมบูรณ์แบบ
Juan

68
ที่จริงแล้วมันได้รับอนุญาตเพราะ php เป็นเกลียวเหมือนนรกทั้งหมด
Eric G
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.