PHP: วิธีการลบองค์ประกอบที่เฉพาะเจาะจงจากอาร์เรย์?


160

ฉันจะลบองค์ประกอบออกจากอาร์เรย์ได้อย่างไรเมื่อฉันรู้ชื่อองค์ประกอบ ตัวอย่างเช่น:

ฉันมีอาเรย์:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');

ผู้ใช้เข้าสู่ strawberry

strawberry จะถูกลบออก

เพื่ออธิบายอย่างเต็มที่:

ฉันมีฐานข้อมูลที่จัดเก็บรายการที่คั่นด้วยเครื่องหมายจุลภาค รหัสจะดึงในรายการตามตัวเลือกของผู้ใช้ที่ตัวเลือกนั้นอยู่ ดังนั้นหากพวกเขาเลือกสตรอเบอร์รี่พวกเขาจะดึงรหัสในทุก ๆ รายการที่สตรอเบอร์รี่ตั้งอยู่จากนั้นแปลงเป็นอาร์เรย์โดยใช้ split () ฉันต้องการให้พวกเขานำรายการที่ผู้ใช้เลือกตัวอย่างเช่นสตรอเบอร์รี่ออกจากอาร์เรย์


4
คำถามเดียวกัน: stackoverflow.com/questions/7225070/…
trante

1
อีกคำถามเดียวกัน: stackoverflow.com/questions/1883421/…
Eric Lavoie

1
คำถามเดียวกันเพิ่มเติม: stackoverflow.com/questions/369602/…
อเล็กซ์

คำตอบ:


296

ใช้array_searchเพื่อรับคีย์และลบออกด้วยunsetหากพบ:

if (($key = array_search('strawberry', $array)) !== false) {
    unset($array[$key]);
}

array_searchส่งคืนfalse ( nullจนถึง PHP 4.2.0) หากไม่พบรายการ

และหากมีหลายรายการที่มีค่าเท่ากันคุณสามารถใช้array_keysเพื่อรับกุญแจไปยังทุกรายการ:

foreach (array_keys($array, 'strawberry') as $key) {
    unset($array[$key]);
}

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

1
ในขณะที่ (odbc_fetch_row ($ runqueryGetSubmenus)) {$ submenuList = odbc_result ($ runqueryGetSubmenus, "submenus"); $ submenuArray = split (',', $ submenuList); if (($ key = array_search ($ name, $ submenuArray))! == false) {unset ($ submenuArray [$ key]); }}
dcp3450

@ dcp3450: และสิ่งที่คุณทำกับ$submenuArray? (โปรดทราบว่าด้วยการวนซ้ำแต่ละครั้ง$submenuArrayจะถูกเขียนทับ)
Gumbo

ฉันอัปเดตคำถามเพื่ออธิบายให้ดีขึ้น โดยทั่วไปโค้ดจะวนซ้ำผ่านรายการต่างๆในฐานข้อมูลเพื่อลบรายการที่เลือก "strawberry" ในตัวอย่างนี้ ดังนั้นผู้ใช้เข้าสู่การเลือก => รหัสค้นหาภายใต้เมนูย่อยและค้นหารายการใด ๆ ที่มีตัวเลือก => เปลี่ยนรายการนั้นเป็นอาร์เรย์ => ลบตัวเลือกที่เลือก
dcp3450

1
ฉันเข้าใจแล้ว! ฉันไม่ได้เขียนอาร์เรย์ใหม่กลับไปที่ฐานข้อมูล พลาดง่าย ๆ เมื่อคุณจ้องที่โค้ดนาน ๆ
dcp3450

153

ใช้array_diff()สำหรับโซลูชัน 1 บรรทัด:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi', 'strawberry'); //throw in another 'strawberry' to demonstrate that it removes multiple instances of the string
$array_without_strawberries = array_diff($array, array('strawberry'));
print_r($array_without_strawberries);

... ไม่จำเป็นต้องมีฟังก์ชั่นพิเศษหรือ foreach loop


8
วิธีนี้เป็นวิธีที่อ่านง่ายกว่าวิธีที่อยู่บนสุด
Robbert

แม้ว่าstrawberryจะไม่ได้อยู่ในอาร์เรย์เริ่มต้นก็จะมีอยู่ใน$array_without_strawberriesอาร์เรย์ - รหัสอันตรายถ้าคุณต้องการให้แน่ใจว่าองค์ประกอบที่กำหนดไม่ได้อยู่ในอาร์เรย์
Erfan

5
@Erfan การเรียกร้องของคุณไม่ถูกต้อง $a = array_diff(array(), array('strawberry'));- $ a คืออาร์เรย์ว่าง
นักเลง

1
คุณถูก @bancer - ฉันอาจจะคิดว่า array_intersect หรืออะไรบางอย่าง
Erfan

1
array_diff () หรูหรากว่าคำตอบที่ทำเครื่องหมายไว้
Dom DaFonte

36
if (in_array('strawberry', $array)) 
{
    unset($array[array_search('strawberry',$array)]);
}

2
คุณควรทดสอบว่าสตรอเบอร์รี่อยู่ในแถวหรือไม่
Gumbo

การปฏิบัติตามคำแนะนำของ Gumbo ได้แก้ไขคำตอบเพื่อรวมการตรวจสอบองค์ประกอบก่อนที่จะลบออกจากอาร์เรย์
John Conde

2
โปรดทราบว่าดัชนีไม่ได้ถูกจัดแนวใหม่หลังจากลบองค์ประกอบเฉพาะ กล่าวอีกนัยหนึ่งลำดับดัชนีจะมีช่องว่าง หากคุณลบ 'สตรอเบอร์รี่' จากตัวอย่างของคุณ 'กีวี' จะยังคงมีดัชนี 4 และดัชนี 2 จะหายไป มันสำคัญถ้ารหัสของคุณขึ้นอยู่กับความสมบูรณ์ของลำดับดัชนีเช่นสำหรับ ($ i = 0; $ i <.. , $ i ++) ลูปทำ
the-banana-king

2
$my_array = array_values($my_array);ในการเพิ่มสิ่งที่กล้วยกษัตริย์กล่าวว่าถ้าคุณต้องการที่จะดัชนีอาร์เรย์ก็ทำ
ryeguy

2
ขณะที่วิธีนี้ถูกต้องมันจะค้นหาอาเรย์สองครั้ง ( in_arrayและarray_search) การใช้การคืนสินค้าarray_searchตามคำตอบของ Gumbo นั้นมีประสิทธิภาพมากกว่า
Bogdan D

21

หากคุณใช้อาเรย์ธรรมดาที่นี่ (ซึ่งดูเหมือนกับตัวอักษร) คุณควรใช้รหัสนี้แทน:

if (($key = array_search('strawberry', $array)) !== false) {
    array_splice($array, $key, 1);
}

unset($array[$key]) ลบองค์ประกอบเท่านั้น แต่ไม่ได้จัดลำดับอาร์เรย์ธรรมดาใหม่

สมมติว่าเรามีอาร์เรย์และใช้ array_splice:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
array_splice($array, 2, 1);
json_encode($array); 
// yields the array ['apple', 'orange', 'blueberry', 'kiwi']

เปรียบเทียบกับ unset:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
unset($array[2]);
json_encode($array);
// yields an object {"0": "apple", "1": "orange", "3": "blueberry", "4": "kiwi"}

โปรดสังเกตว่าunset($array[$key])จะไม่เรียงลำดับอาร์เรย์อีกครั้ง


อย่างเป็นทางการunsetจะไม่ส่งคืนสิ่งใด ดังนั้นจึงjson_encode(unset($array[2]))ไม่เหมาะสำหรับการเปรียบเทียบ
robsch

ตรงนี้เป็นสิ่งที่ฉันต้องการ thaks เพื่อ ericluwj
ana

12

คุณสามารถใช้ตัวกรองอาร์เรย์เพื่อลบรายการตามเงื่อนไขที่ระบุใน$v:

$arr = array_filter($arr, function($v){
    return $v != 'some_value';
});

downvote คุณภาพต่ำนี้ (เพราะมันเป็นคำตอบที่รหัสเท่านั้นและให้ข้อผิดพลาดการแยกก) เป็นซ้ำของวิธี D.Martin array_filter()ว่าแค่ใช้ฟังก์ชั่นภายในที่ไม่ระบุชื่อ ในขณะที่ฉันจะใช้ฟังก์ชันที่ไม่ระบุชื่อเป็นการส่วนตัว แต่ฉันเชื่อว่าการกระทำที่ถูกต้องใน SO จะเป็นการแสดงความคิดเห็นหรือแก้ไขคำตอบของ D.Martin หากคุณต้องการทำการปรับปรุงแบบไมโครเพื่อให้หน้านี้ไม่ป่อง โปรดลบคำตอบที่ซ้ำกันนี้
mickmackusa

4

จะเป็นเช่นนี้:

 function rmv_val($var)
 {
     return(!($var == 'strawberry'));
 }

 $array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');

 $array_res = array_filter($array, "rmv_val");

4

นี่เป็นการทำซ้ำง่าย ๆ ที่สามารถลบค่าหลายค่าในอาร์เรย์

    // Your array
    $list = array("apple", "orange", "strawberry", "lemon", "banana");

    // Initilize what to delete
    $delete_val = array("orange", "lemon", "banana");

    // Search for the array key and unset   
    foreach($delete_val as $key){
        $keyToDelete = array_search($key, $list);
        unset($list[$keyToDelete]);
    }

นี่คือการไม่มีประสิทธิภาพการเปลี่ยนบ้านรีดสำหรับสิ่งที่นักพัฒนาของ PHP array_diff()ได้สร้างไว้แล้วใน วิธีนี้ได้รับการโหวตสามครั้ง ไม่มีใครควรค้นหาคำตอบนี้มีประโยชน์หรือใช้ในโครงการของตนเอง ฉันขอแนะนำให้ลบคำตอบนี้เพื่อเป็นการช่วยให้บัญชีของคุณมีคำตอบที่มีคุณภาพต่ำลดคำตอบที่ขยายตัวในหน้านี้และรับตราที่มีระเบียบวินัย ฉันจะเลื่อน downvote ของฉันเพื่อที่คุณจะได้มีเวลาลบสำหรับรางวัล
mickmackusa

4

เพียงแค่คุณสามารถทำบรรทัดเดียวมันจะถูกลบองค์ประกอบจากอาร์เรย์


$array=array_diff($array,['strawberry']);


3

ฉันกำลังใช้ฟังก์ชั่นนี้:

function array_delete($del_val, $array) {
    if(is_array($del_val)) {
         foreach ($del_val as $del_key => $del_value) {
            foreach ($array as $key => $value){
                if ($value == $del_value) {
                    unset($array[$key]);
                }
            }
        }
    } else {
        foreach ($array as $key => $value){
            if ($value == $del_val) {
                unset($array[$key]);
            }
        }
    }
    return array_values($array);
}

คุณสามารถป้อนอาร์เรย์หรือเฉพาะสตริงที่มีองค์ประกอบที่ควรลบออก เขียนแบบนี้:

$detils = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
$detils = array_delete(array('orange', 'apple'), $detils);

หรือ

$detils = array_delete('orange', $detils);

มันจะทำดัชนีซ้ำอีกครั้ง


2
นี่เป็นสิ่งที่ซับซ้อนและน่ากลัวอย่างมาก วิธีนี้ได้รับ 3 upvotes ได้อย่างไร!
mickmackusa

2

คำถามนี้มีคำตอบหลายข้อ แต่ฉันต้องการเพิ่มบางอย่างเพิ่มเติมเพราะเมื่อฉันใช้unsetหรือarray_diffฉันมีปัญหาหลายอย่างในการเล่นกับดัชนีของอาร์เรย์ใหม่เมื่อองค์ประกอบที่เฉพาะเจาะจงถูกลบออก (เพราะบันทึกดัชนีเริ่มต้น)

ฉันกลับไปที่ตัวอย่าง:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
$array_without_strawberries = array_diff($array, array('strawberry'));

หรือ

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
unset($array[array_search('strawberry', $array)]);

หากคุณพิมพ์ผลคุณจะได้รับ:

foreach ($array_without_strawberries as $data) {
   print_r($data);
}

ผลลัพธ์ :

> apple
> orange
> blueberry
> kiwi

แต่ดัชนีจะถูกบันทึกไว้และคุณจะสามารถเข้าถึงองค์ประกอบของคุณเช่น:

$array_without_strawberries[0] > apple
$array_without_strawberries[1] > orange
$array_without_strawberries[3] > blueberry
$array_without_strawberries[4] > kiwi

ดังนั้นอาร์เรย์สุดท้ายจึงไม่ได้จัดทำดัชนีใหม่ ดังนั้นคุณต้องเพิ่มหลังจากunsetหรือarray_diff:

$array_without_strawberries = array_values($array);

หลังจากนั้นอาร์เรย์ของคุณจะมีดัชนีปกติ:

$array_without_strawberries[0] > apple
$array_without_strawberries[1] > orange
$array_without_strawberries[2] > blueberry
$array_without_strawberries[3] > kiwi

เกี่ยวข้องกับโพสต์นี้: เรย์ดัชนีอีกครั้ง

ป้อนคำอธิบายรูปภาพที่นี่

หวังว่ามันจะช่วย


1

วิธีที่ดีกว่าอาจจะทำให้ค่าของคุณเป็นกุญแจในอาเรย์แบบเชื่อมโยงแล้วเรียกarray_keys()ใช้เมื่อคุณต้องการอาเรย์จริง ด้วยวิธีนี้คุณไม่จำเป็นต้องใช้array_searchเพื่อค้นหาองค์ประกอบของคุณ


1
โพสต์ของคุณเป็นความคิดเห็นไม่ใช่คำตอบ โปรดลบและโพสต์ภายใต้คำถามนั้นเอง
mickmackusa

1

คำตอบของอาร์เรย์ PHPจะลบตามค่า (ไม่ใช่คีย์) กำหนดโดย https://stackoverflow.com/users/924109/rok-kralj

IMO เป็นคำตอบที่ดีที่สุดเมื่อลบออกและไม่กลายพันธุ์

array_diff( [312, 401, 15, 401, 3], [401] ) // removing 401 returns [312, 15, 3]

มันสรุปได้เป็นอย่างดีคุณสามารถลบองค์ประกอบได้มากเท่าที่คุณต้องการในเวลาเดียวกันถ้าคุณต้องการ

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


1

ฉันกำลังมองหาคำตอบสำหรับคำถามเดียวกันและพบกับหัวข้อนี้ ผมเห็นสองวิธีหลัก: การรวมกันของarray_search& และการใช้งานของunset array_diffจากภาพรวมในครั้งแรกดูเหมือนว่าวิธีแรกจะเร็วกว่าเนื่องจากไม่ต้องการการสร้างอาร์เรย์เพิ่มเติม (เช่นเมื่อใช้array_diff) แต่ฉันเขียนเกณฑ์มาตรฐานขนาดเล็กและทำให้แน่ใจว่าวิธีที่สองนั้นไม่เพียง แต่กระชับเท่านั้น แต่ยังเร็วขึ้นด้วย! ดีใจที่ได้แบ่งปันสิ่งนี้กับคุณ :)

https://glot.io/snippets/f6ow6biaol


0

ฉันต้องการใช้array_key_existsเพื่อค้นหาคีย์ในอาร์เรย์ดังนี้

Array([0]=>'A',[1]=>'B',['key'=>'value'])

เพื่อค้นหาสิ่งที่ระบุอย่างมีประสิทธิภาพเนื่องจาก array_search และ in_array () ไม่ทำงานที่นี่ และอย่าเอาสิ่งที่มีunset ()

ฉันคิดว่ามันจะช่วยใครซักคน


0

สร้างอาร์เรย์ที่เป็นตัวเลขด้วยการลบค่า Array โดยเฉพาะ

    <?php
    // create a "numeric" array
    $animals = array('monitor', 'cpu', 'mouse', 'ram', 'wifi', 'usb', 'pendrive');

    //Normarl display
    print_r($animals);
    echo "<br/><br/>";

    //If splice the array
    //array_splice($animals, 2, 2);
    unset($animals[3]); // you can unset the particular value
    print_r($animals);

    ?>

คุณสามารถอ้างอิงลิงค์นี้ ..


downvote คำถามจะถามอย่างชัดเจนว่าให้ลบค่าตามค่า (ไม่ใช่คีย์) คำตอบนี้ไม่มีประโยชน์โปรดลบ
mickmackusa

0
$remove= "strawberry";
$array = ["apple", "orange", "strawberry", "blueberry", "kiwi"];
foreach ($array as $key => $value) {
        if ($value!=$remove) {
        echo $value.'<br/>';
                continue;
        }
}

คำตอบนี้ไม่ได้ลบตัวเลือกที่ต้องการ
Nigel Ren

-1

ใช้array_seach()ลองทำสิ่งต่อไปนี้:

if(($key = array_search($del_val, $messages)) !== false) {
    unset($messages[$key]);
}

array_search()ผลตอบแทนที่สำคัญขององค์ประกอบที่พบซึ่งสามารถใช้ในการลบองค์ประกอบที่จาก array unset()เดิมโดยใช้ มันจะส่งคืนFALSEเมื่อเกิดความล้มเหลวอย่างไรก็ตามสามารถส่งคืนค่า "เท็จ" ต่อความสำเร็จได้ ( 0ตัวอย่างเช่นรหัสของคุณ) ซึ่งเป็นสาเหตุที่ใช้!==ตัวดำเนินการเปรียบเทียบที่เข้มงวด

if()คำสั่งจะตรวจสอบว่าarray_search()กลับมีค่าและจะดำเนินการถ้ามันไม่ได้


3
downvote นี่เป็นวิธีการซ้ำซ้อนของ Gumbo (ซึ่งปัจจุบันได้รับการยอมรับ) ซึ่งโพสต์เมื่อหลายปีก่อน คำตอบที่ซ้ำกันไม่มีค่าและทำให้เกิดการขยายหน้าเว็บโดยไม่จำเป็นเท่านั้น โปรดลบคำตอบของคุณ หากคุณต้องการที่จะอธิบายคำตอบของ Gumbo ให้แก้ไขด้วยคำตอบของเขาหรือขอให้ Gumbo ขยายคำตอบของตัวเองออกไป ..
mickmackusa

-1
unset($array[array_search('strawberry', $array)]);

2
downvote array_search()- unset()วิธีการถูกโพสต์แล้วโดยจอห์นเดปีก่อนที่จะแสดงความนับถือ คำตอบที่ซ้ำกันไม่มีคุณค่าต่อผู้อ่านและแท้จริงแล้วเป็นความไม่สะดวกเพราะเสียเวลาในขณะที่เลื่อนและอ่านข้อมูลซ้ำซ้อน โปรดลบคำตอบนี้
mickmackusa

-1
<?php 
$array = array("apple", "orange", "strawberry", "blueberry", "kiwi");
$delete = "strawberry";
$index = array_search($delete, $array);
array_splice($array, $index, 1);
var_dump($array);
?>

2
คุณสามารถปรับปรุงคำตอบนี้ได้โดยเขียนประโยคหนึ่งหรือสองประโยคเกี่ยวกับ a) โค้ดทำอะไรและ b) ทำไมคุณคิดว่าเป็นตัวเลือกในคำตอบอื่น ๆ ทั้งหมด
Robin Mackenzie

-1
foreach ($get_dept as $key5 => $dept_value) {
                if ($request->role_id == 5 || $request->role_id == 6){
                    array_splice($get_dept, $key5, 1);
                }
            }

4
นอกเหนือจากคำตอบที่คุณให้มาโปรดพิจารณาให้คำอธิบายโดยย่อเกี่ยวกับสาเหตุและวิธีการนี้ในการแก้ไขปัญหา
jtate

-2
$detils = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
     function remove_embpty($values)
     {
        if($values=='orange')
        {
            $values='any name';
        }
        return $values;
     }
     $detils=array_map('remove_embpty',$detils);
    print_r($detils);

2
โปรดเพิ่มคำอธิบาย มันแก้ปัญหาได้อย่างไร
Rahil Wazir

คำตอบของคุณจะแทนที่องค์ประกอบหนึ่งของอาเรย์เป็น NO อื่นเพื่อลบองค์ประกอบ
ahmed hamdy

downvote คำตอบนี้ไม่ได้ให้ผลลัพธ์ที่คาดหวัง โปรดลบคำตอบที่ไม่ถูกต้องนี้
mickmackusa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.