PHP: Làm thế nào để loại bỏ phần tử cụ thể khỏi một mảng?


159

Làm cách nào để xóa phần tử khỏi mảng khi tôi biết tên phần tử? ví dụ:

Tôi có một mảng:

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

người dùng vào strawberry

strawberry bị xóa.

Để giải thích đầy đủ:

Tôi có một cơ sở dữ liệu lưu trữ một danh sách các mục được phân tách bằng dấu phẩy. Mã kéo trong danh sách dựa trên lựa chọn của người dùng nơi lựa chọn đó được đặt. Vì vậy, nếu họ chọn dâu, họ kéo mã trong mỗi mục nhập là dâu được định vị sau đó chuyển đổi nó thành một mảng bằng cách sử dụng split (). Tôi muốn họ loại bỏ các mục người dùng đã chọn, ví dụ như dâu tây này, khỏi mảng.



1
Một câu hỏi tương tự khác: stackoverflow.com/questions/1883421/ Kẻ
Eric Lavoie

1
nhiều câu hỏi tương tự: stackoverflow.com/questions/369602/ Mạnh
Alex

Câu trả lời:


295

Sử dụng array_searchđể lấy chìa khóa và xóa nó unsetnếu tìm thấy:

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

array_searchtrả về false ( null cho đến PHP 4.2.0) nếu không tìm thấy mục nào.

Và nếu có thể có nhiều mục có cùng giá trị, bạn có thể sử dụng array_keysđể lấy khóa cho tất cả các mục:

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

Nhận một kết quả kỳ lạ. Tôi đã sử dụng đề xuất đầu tiên của bạn vì sẽ luôn chỉ có một ví dụ. Để kiểm tra nó tôi chỉ cần nó xuất ra giá trị khóa. Đã làm việc. Tuy nhiên, nó sẽ không bỏ qua.
dcp3450

1
while (odbc_fetch_row ($ runqueryGetSubmenus)) {$ submenuList = odbc_result ($ runqueryGetSubmenus, "menu con"); $ submenuArray = split (',', $ submenuList); if (($ key = Array_search ($ name, $ submenuArray))! == false) {unset ($ submenuArray [$ key]); }}
dcp3450

@ dcp3450: Và bạn sẽ làm gì với $submenuArray? (Lưu ý rằng với mỗi vòng lặp $submenuArraysẽ bị ghi đè.)
Gumbo

tôi cập nhật câu hỏi của tôi để giải thích rõ hơn. Về cơ bản các vòng lặp mã thông qua các mục trong cơ sở dữ liệu loại bỏ các mục đã chọn, "dâu tây" trong ví dụ này. Vì vậy, người dùng nhập một lựa chọn => mã tìm kiếm trong menu con và tìm thấy bất kỳ danh sách nào có tùy chọn đó => biến danh sách đó thành một mảng => loại bỏ tùy chọn đã chọn.
dcp3450

1
Tôi hiểu rồi! Tôi đã không viết lại mảng mới trở lại DB. Dễ bỏ lỡ công cụ khi bạn nhìn chằm chằm vào mã quá lâu.
dcp3450

153

Sử dụng array_diff()cho giải pháp 1 dòng:

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

... Không cần thêm chức năng hoặc vòng lặp foreach.


8
Giải pháp này dễ đọc hơn những giải pháp hàng đầu.
Robbert

Mặc dù nếu strawberrykhông có trong mảng ban đầu, nó sẽ trở nên có sẵn trong $array_without_strawberriesmảng - mã nguy hiểm nếu bạn muốn đảm bảo rằng một phần tử đã cho không nằm trong một mảng.
Erfan

5
@Erfan Yêu cầu của bạn là sai. $a = array_diff(array(), array('strawberry'));- $ a là một mảng trống.
vũ công

1
Bạn nói đúng @bancer - Tôi có lẽ đã nghĩ đến mảng_intersect hoặc thứ gì đó.
Erfan

1
Array_diff () thanh lịch hơn câu trả lời được đánh dấu.
Dom DaFonte

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

2
Bạn nên kiểm tra xem dâu có ở trong mảng không.
Gumbo

Làm theo lời khuyên đã được sửa đổi của Gumbo để bao gồm xác minh thành phần trước khi xóa nó khỏi mảng.
John Conde

2
Ngoài ra, hãy nhớ rằng các chỉ số không được sắp xếp lại sau khi xóa một yếu tố cụ thể. Nói cách khác, chuỗi chỉ mục sẽ có khoảng trống sau đó. Nếu bạn xóa 'dâu' khỏi ví dụ của mình, 'kiwi' vẫn sẽ có chỉ số 4 và chỉ số 2 sẽ biến mất. Nó quan trọng nếu mã của bạn phụ thuộc vào tính đầy đủ của chuỗi chỉ mục, ví dụ như các vòng lặp ($ i = 0; $ i <.., $ i ++) thực hiện.
the-Banana-king

2
Để thêm vào những gì vua-chuối nói, nếu bạn muốn reindex mảng, chỉ cần làm $my_array = array_values($my_array);.
ryeguy

2
Trong khi giải pháp này là chính xác, nó tìm kiếm mảng TWICE ( in_arrayarray_search). Sử dụng trả về array_searchnhư trong câu trả lời của Gumbo có hiệu quả hơn
Bogdan D

21

Nếu bạn đang sử dụng một mảng đơn giản ở đây (có vẻ như trường hợp này), bạn nên sử dụng mã này thay thế:

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

unset($array[$key]) chỉ loại bỏ phần tử nhưng không sắp xếp lại mảng đơn giản.

Giả sử chúng ta có một mảng và sử dụng mảng_splice:

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

So với 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"}

Lưu ý làm thế nào unset($array[$key])không sắp xếp lại mảng.


Chính thức unsetkhông trả lại bất cứ điều gì. Vì vậy, json_encode(unset($array[2]))không thích hợp để so sánh.
robsch

đây chính xác là những gì tôi cần, từ đây đến ericluwj
ana

12

Bạn có thể sử dụng bộ lọc mảng để loại bỏ các mục theo một điều kiện cụ thể trên $v:

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

Downvote. Chất lượng thấp này (vì đây là câu trả lời chỉ có mã và đưa ra lỗi phân tích cú pháp) là một bản sao của phương thức D.Martin chỉ sử dụng một hàm ẩn danh bên trong array_filter(). Mặc dù cá nhân tôi sẽ sử dụng một chức năng ẩn danh trong triển khai của mình, tôi tin rằng hành động chính xác trên SO sẽ là nhận xét hoặc chỉnh sửa câu trả lời của D.Martin nếu bạn muốn cải thiện vi mô để trang này không bị phồng lên. Vui lòng xóa câu trả lời trùng lặp này.
mickmackusa

4

Sẽ như thế này:

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

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

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

4

Đây là một sự lặp lại đơn giản có thể xóa nhiều giá trị trong mảng.

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

Đây là một sự thay thế không hiệu quả, tại nhà cho những gì các nhà phát triển của PHP đã tạo ra array_diff(). Làm thế nào điều này có được ba upvote. Không ai nên tìm câu trả lời này hữu ích hoặc sử dụng nó trong các dự án của riêng họ. Tôi khuyên bạn nên xóa câu trả lời này - điều này sẽ phục vụ để giải phóng tài khoản của bạn về câu trả lời chất lượng thấp, giảm câu trả lời trên trang này và kiếm cho bạn huy hiệu Kỷ luật. Tôi sẽ hoãn downvote của tôi để bạn có thời gian xóa để nhận phần thưởng.
mickmackusa

4

Chỉ cần bạn có thể làm một dòng .it sẽ loại bỏ phần tử khỏi mảng


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


3

Tôi hiện đang sử dụng chức năng này:

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

Bạn có thể nhập một mảng hoặc chỉ một chuỗi có (các) phần tử cần được loại bỏ. Viết nó như thế này:

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

HOẶC LÀ

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

Nó cũng sẽ giới thiệu lại nó.


2
Điều này là khủng khiếp và hỗn loạn. Làm thế nào mà điều này đạt được 3 upvote?!?
mickmackusa

2

Câu hỏi này có một số câu trả lời nhưng tôi muốn thêm một số câu hỏi vì khi tôi sử dụng unsethoặc array_difftôi gặp một số vấn đề khi chơi với các chỉ mục của mảng mới khi phần tử cụ thể bị xóa (vì chỉ mục ban đầu được lưu)

Tôi lấy lại ví dụ:

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

hoặc là

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

Nếu bạn in kết quả, bạn sẽ nhận được:

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

Kết quả :

> apple
> orange
> blueberry
> kiwi

Nhưng các chỉ mục sẽ được lưu và do đó bạn sẽ truy cập vào phần tử của mình như:

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

Và do đó, mảng cuối cùng không được lập chỉ mục lại. Vì vậy, bạn cần thêm sau unsethoặc array_diff:

$array_without_strawberries = array_values($array);

Sau đó, mảng của bạn sẽ có một chỉ mục bình thường:

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

Liên quan đến bài đăng này: Re-Index Array

nhập mô tả hình ảnh ở đây

Hy vọng nó sẽ giúp


1

Một cách tiếp cận tốt hơn có thể là giữ các giá trị của bạn dưới dạng các khóa trong một mảng kết hợp, và sau đó gọi array_keys()nó khi bạn muốn mảng thực tế. Bằng cách đó bạn không cần sử dụng array_searchđể tìm yếu tố của mình.


1
Bài viết của bạn là một bình luận không phải là một câu trả lời. Vui lòng xóa và gửi theo câu hỏi chính nó.
mickmackusa

1

Câu trả lời cho việc xóa mảng PHP theo giá trị (không phải khóa) Được đưa ra bởi https://stackoverflow.com/users/924109/rok-kralj

IMO là câu trả lời tốt nhất vì nó loại bỏ và không biến đổi

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

Nó khái quát độc đáo, bạn có thể loại bỏ bao nhiêu yếu tố tùy thích cùng một lúc, nếu bạn muốn.

Tuyên bố miễn trừ trách nhiệm: Lưu ý rằng giải pháp của tôi tạo ra một bản sao mới của mảng trong khi vẫn giữ nguyên cái cũ trái ngược với câu trả lời được chấp nhận sẽ đột biến. Nó có thể chậm hơn một chút vì điều này.


1

Tôi đang tìm kiếm câu trả lời cho cùng một câu hỏi và tình cờ thấy chủ đề này. Tôi thấy hai cách chính: sự kết hợp của array_search& unsetvà việc sử dụng array_diff. Thoạt nhìn, dường như phương pháp đầu tiên sẽ nhanh hơn, vì không yêu cầu tạo ra một mảng bổ sung (như khi sử dụng array_diff). Nhưng tôi đã viết một điểm chuẩn nhỏ và đảm bảo rằng phương pháp thứ hai không chỉ ngắn gọn hơn mà còn nhanh hơn! Vui mừng chia sẻ điều này với bạn. :)

https://glot.io/snippets/f6ow6biaol


0

Tôi muốn sử dụng mảng_key_exists để tìm kiếm các khóa trong mảng như:

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

để tìm chỉ định một cách hiệu quả, vì mảng_search và in_array () không hoạt động ở đây. Và loại bỏ các công cụ với unset () .

Tôi nghĩ nó sẽ giúp được ai đó.


0

Tạo mảng số với xóa giá trị mảng cụ thể

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

    ?>

Bạn có thể tham khảo liên kết này ..


Downvote. Câu hỏi rõ ràng yêu cầu loại bỏ một giá trị dựa trên giá trị (không phải khóa). Câu trả lời này là vô ích, xin vui lòng xóa.
mickmackusa

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

Câu trả lời này thậm chí không loại bỏ tùy chọn cần thiết.
Nigel Ren

-1

Sử dụng array_seach(), hãy thử như sau:

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

array_search()trả về khóa của phần tử mà nó tìm thấy, có thể được sử dụng để loại bỏ phần tử đó khỏi mảng ban đầu bằng cách sử dụng unset(). Nó sẽ trở lại FALSEvào thất bại, tuy nhiên nó có thể trở lại một "falsey" giá trị về thành công (key của bạn có thể 0ví dụ), đó là lý do tại sao việc so sánh nghiêm ngặt !==điều hành được sử dụng.

Câu if()lệnh sẽ kiểm tra xem có array_search()trả về một giá trị hay không và sẽ chỉ thực hiện một hành động nếu nó đã làm.


3
Downvote. Đây là bản sao của phương pháp Gumbo (hiện là giải pháp được chấp nhận) đã được đăng trước nhiều năm. Câu trả lời trùng lặp không có giá trị và chỉ gây ra sự phình to trang không cần thiết. Hãy xóa câu trả lời của bạn. Nếu bạn muốn giải thích câu trả lời của Gumbo, hãy chỉnh sửa câu trả lời của anh ấy hoặc yêu cầu Gumbo mở rộng câu trả lời của anh ấy ..
mickmackusa

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

2
Downvote. Các array_search()- unset()phương pháp đã được đăng bởi John Conde năm trước bạn. Câu trả lời trùng lặp không có giá trị với độc giả và thực sự là một sự bất tiện vì lãng phí thời gian trong khi cuộn và đọc thông tin dư thừa. Hãy xóa câu trả lời này.
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
Bạn có thể cải thiện câu trả lời này bằng cách viết một hoặc hai câu về a) những gì mã làm và b) tại sao bạn nghĩ rằng đó là một lựa chọn trong số tất cả các câu trả lời khác.
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
Ngoài câu trả lời bạn đã cung cấp, vui lòng xem xét việc cung cấp giải thích ngắn gọn về lý do và cách khắc phục sự cố này.
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
Xin vui lòng thêm giải thích. Làm thế nào nó giải quyết vấn đề.
Rahil Wazir

câu trả lời của bạn thay thế một phần tử của mảng thành NO khác để loại bỏ một phần tử
ahmed hamdy

Downvote. Câu trả lời này không cung cấp đầu ra dự kiến. Hãy xóa câu trả lời không chính xác này.
mickmackusa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.