PHP: ¿Cómo eliminar un elemento específico de una matriz?

160

¿Cómo elimino un elemento de una matriz cuando conozco el nombre del elemento? por ejemplo:

Tengo una matriz:

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

el usuario ingresa strawberry

strawberry es removido.

Para explicar completamente:

Tengo una base de datos que almacena una lista de elementos separados por una coma. El código extrae la lista en función de una elección del usuario donde se encuentra esa opción. Entonces, si eligen la fresa, codifican las entradas en cada entrada donde se encuentra la fresa y luego la convierte en una matriz usando split (). Quiero que eliminen los elementos elegidos por el usuario, por ejemplo, fresa, de la matriz.

dcp3450
fuente
44
Misma pregunta: stackoverflow.com/questions/7225070/…
trante
1
Otra misma pregunta: stackoverflow.com/questions/1883421/…
Eric Lavoie
1
más misma pregunta: stackoverflow.com/questions/369602/…
Alex

Respuestas:

296

Use array_searchpara obtener la clave y eliminarla unsetsi se encuentra:

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

array_searchdevuelve falso ( nulo hasta PHP 4.2.0) si no se ha encontrado ningún elemento.

Y si puede haber varios elementos con el mismo valor, puede usar array_keyspara obtener las claves de todos los elementos:

foreach (array_keys($array, 'strawberry') as $key) {
    unset($array[$key]);
}
Gumbo
fuente
Obteniendo un resultado extraño. Usé tu primera sugerencia ya que siempre habrá una sola instancia. Para probarlo, simplemente hice que produjera el valor clave. Trabajó. Sin embargo, no se desarmará.
dcp3450
1
while (odbc_fetch_row ($ runqueryGetSubmenus)) {$ submenuList = odbc_result ($ runqueryGetSubmenus, "submenus"); $ submenuArray = split (',', $ submenuList); if (($ key = array_search ($ name, $ submenuArray))! == false) {unset ($ submenuArray [$ key]); }}
dcp3450
@ dcp3450: ¿Y con qué haces $submenuArray? (Tenga en cuenta que con cada ciclo $submenuArrayse sobrescribirá).
Gumbo
Actualicé mi pregunta para explicar mejor. Básicamente, el código recorre las entradas en una base de datos eliminando los elementos elegidos, "fresa" en este ejemplo. Entonces, el usuario ingresa una selección => el código busca en submenús y encuentra cualquier lista que tenga esa opción => convierte esa lista en una matriz => elimina la opción elegida.
dcp3450
1
¡Lo tengo! No estaba reescribiendo la nueva matriz a la base de datos. Cosas fáciles de perder cuando mira el código durante tanto tiempo.
dcp3450
153

Uso array_diff()para solución de 1 línea:

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

... No se necesitan funciones adicionales ni bucles foreach.

males
fuente
8
Esta solución es mucho más legible que las mejores.
Robbert
Aunque si strawberryno está en la matriz inicial, estará disponible en la $array_without_strawberriesmatriz: código peligroso si desea asegurarse de que un elemento dado no esté en una matriz.
Erfan
55
@Erfan Tu reclamo es incorrecto. $a = array_diff(array(), array('strawberry'));- $ a es una matriz vacía.
bancer
1
Tienes razón @bancer: probablemente estaba pensando en array_intersect o algo así.
Erfan
1
array_diff () es más elegante que la respuesta marcada.
Dom DaFonte
36
if (in_array('strawberry', $array)) 
{
    unset($array[array_search('strawberry',$array)]);
}
John Conde
fuente
2
Debe probar si la fresa está en la matriz en absoluto.
Gumbo
Siguiendo el consejo de Gumbo, se modificó la respuesta para incluir la verificación del elemento antes de eliminarlo de la matriz.
John Conde
2
También tenga en cuenta que los índices no se realinean después de eliminar un elemento en particular. En otras palabras, la secuencia de índice tendrá huecos entonces. Si elimina 'fresa' de su ejemplo, 'kiwi' seguirá teniendo el índice 4, y el índice 2 simplemente desaparecerá. Importa si su código se basa en la integridad de la secuencia de índice, como por ejemplo para los bucles ($ i = 0; $ i <.., $ i ++).
the-banana-king
2
Para agregar a lo que dijo el rey de los plátanos, si desea reindexar la matriz, simplemente haga $my_array = array_values($my_array);.
ryeguy
2
Si bien esta solución es correcta, busca la matriz DOS VECES ( in_arrayy array_search). Usar el retorno de array_searchcomo en la respuesta de Gumbo es más efectivo
Bogdan D
21

Si está utilizando una matriz simple aquí (que parece ser el caso), debería usar este código en su lugar:

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

unset($array[$key]) solo elimina el elemento pero no reordena la matriz simple.

Supongamos que tenemos una matriz y usamos array_splice:

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

En comparación con sin configurar:

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

Observe cómo unset($array[$key])no reordena la matriz.

ericluwj
fuente
Oficialmente unsetno devuelve nada. Por json_encode(unset($array[2]))lo tanto, no es apropiado para una comparación.
robsch
esto es exactamente lo que necesito, gracias a ericluwj
ana
12

Puede usar el filtro de matriz para eliminar los elementos por una condición específica en $v:

$arr = array_filter($arr, function($v){
    return $v != 'some_value';
});
srcspider
fuente
Voto a favor. Esta baja calidad (porque es una respuesta de solo código y da un error de análisis) es un duplicado del método de D.Martin que simplemente usa una función anónima en su interior array_filter(). Si bien personalmente usaría una función anónima en mi implementación, creo que la acción correcta en SO sería comentar o editar la respuesta de D.Martin si desea hacer una micro mejora para que esta página no se hinche. Por favor, elimine esta respuesta duplicada.
mickmackusa
4

Será así:

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

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

 $array_res = array_filter($array, "rmv_val");
D.Martin
fuente
4

Esta es una simple reiteración que puede eliminar múltiples valores en la matriz.

    // 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]);
    }
mmr
fuente
Este es un reemplazo ineficiente y casero para lo que los desarrolladores de PHP ya han creado array_diff(). ¿Cómo obtuvo esto tres votos a favor? Nadie debería encontrar esta respuesta útil o usarla en sus propios proyectos. Recomiendo eliminar esta respuesta; esto serviría para liberar su cuenta de una respuesta de baja calidad, reducir la hinchazón de respuestas en esta página y obtener una insignia disciplinada. Pospondré mi voto negativo para que tenga tiempo de eliminarlo para obtener una recompensa.
mickmackusa
4

Solo puedes hacer una sola línea. Se eliminará el elemento de la matriz


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

dılo sürücü
fuente
3

Actualmente estoy usando esta función:

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

Puede ingresar una matriz o solo una cadena con los elementos que deben eliminarse. Escríbelo así:

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

O

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

También lo reindexará.

jankal
fuente
2
Esto es horriblemente complicado y loco. ¿Cómo ganó esto 3 votos a favor?
mickmackusa
2

Esta pregunta tiene varias respuestas, pero quiero agregar algo más porque cuando usé unseto array_difftuve varios problemas para jugar con los índices de la nueva matriz cuando se eliminó el elemento específico (porque se guardan los índices iniciales)

Vuelvo al ejemplo:

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

o

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

Si imprime el resultado obtendrá:

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

Resultado:

> apple
> orange
> blueberry
> kiwi

Pero los índices se guardarán y, por lo tanto, accederá a su elemento como:

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

Y así, la matriz final no se vuelve a indexar. Por lo tanto, debe agregar después de unseto array_diff:

$array_without_strawberries = array_values($array);

Después de eso, su matriz tendrá un índice normal:

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

Relacionado con esta publicación: Re-Index Array

ingrese la descripción de la imagen aquí

Espero que ayude

Jordan Montel
fuente
1

Un mejor enfoque podría ser mantener sus valores como claves en una matriz asociativa, y luego recurrir array_keys()a ella cuando desee una matriz real. De esa manera no necesita usar array_searchpara encontrar su elemento.

jishi
fuente
1
Tu publicación es un comentario, no una respuesta. Por favor, elimine y publique debajo de la pregunta.
mickmackusa
1

La respuesta a la eliminación de la matriz PHP por valor (no clave) Dada por https://stackoverflow.com/users/924109/rok-kralj

IMO es la mejor respuesta ya que elimina y no muta

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

Se generaliza muy bien, puede eliminar tantos elementos como desee al mismo tiempo, si lo desea.

Descargo de responsabilidad: tenga en cuenta que mi solución produce una nueva copia de la matriz mientras mantiene intacta la anterior en contraste con la respuesta aceptada que muta. Puede ser un poco más lento debido a esto.

acosado
fuente
1

Estaba buscando la respuesta a la misma pregunta y encontré este tema. Veo dos formas principales: la combinación de array_search& unsety el uso de array_diff. A primera vista, me pareció que el primer método sería más rápido, ya que no requiere la creación de una matriz adicional (como cuando se usa array_diff). ¡Pero escribí un pequeño punto de referencia y me aseguré de que el segundo método no solo sea más conciso, sino también más rápido! Me alegra compartir esto contigo. :)

https://glot.io/snippets/f6ow6biaol

ПЭХАПЭШНИК
fuente
0

Preferiría usar array_key_exists para buscar claves en matrices como:

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

para encontrar el especificado de manera efectiva, ya que array_search e in_array () no funcionan aquí. Y elimine cosas con unset () .

Creo que ayudará a alguien.

ddsultan
fuente
0

Crear matriz numérica con eliminar un valor de matriz particular

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

    ?>

Puedes referir este enlace.

Sashtha Manik
fuente
Voto a favor. La pregunta claramente pide eliminar un valor basado en el valor (no la clave). Esta respuesta es inútil, por favor elimine.
mickmackusa
0
$remove= "strawberry";
$array = ["apple", "orange", "strawberry", "blueberry", "kiwi"];
foreach ($array as $key => $value) {
        if ($value!=$remove) {
        echo $value.'<br/>';
                continue;
        }
}
Krishna Jonnalagadda
fuente
Esta respuesta ni siquiera elimina la opción requerida.
Nigel Ren
-1

Usando array_seach(), intente lo siguiente:

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

array_search()devuelve la clave del elemento que encuentra, que puede usarse para eliminar ese elemento de la matriz original usando unset(). Volverá FALSEen caso de falla, sin embargo, puede devolver un valor "falsey" en caso de éxito (su clave puede ser, 0por ejemplo), razón por la cual se utiliza el !==operador de comparación estricta .

La if()declaración verificará si array_search()devuelve un valor y solo realizará una acción si lo hizo.

Ravinder Singh
fuente
3
Voto a favor. Este es un duplicado del método de Gumbo (actualmente la solución aceptada) que se publicó años antes que el suyo. Las respuestas duplicadas no tienen valor y solo causan hinchazón de página innecesaria. Por favor borra tu respuesta. Si desea explicar la respuesta de Gumbo, hágalo con una edición de su respuesta o pídale a Gumbo que amplíe su propia respuesta ..
mickmackusa
-1
unset($array[array_search('strawberry', $array)]);
max li
fuente
2
Voto a favor. El array_search()- unset()método ya fue publicada por John Conde años antes que la suya. Las respuestas duplicadas no tienen valor para los lectores y en realidad son un inconveniente debido al tiempo perdido al desplazarse y leer información redundante. Por favor borra esta respuesta.
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);
?>
Onome Mine Adamu
fuente
2
Puede mejorar esta respuesta escribiendo una o dos oraciones sobre a) lo que hace el código yb) por qué cree que es una opción entre todas las otras respuestas.
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);
                }
            }
Rajendra Rajput
fuente
44
Además de la respuesta que ha proporcionado, considere proporcionar una breve explicación de por qué y cómo soluciona el problema.
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);
usuario3296940
fuente
2
Por favor también agregue una explicación. Cómo resuelve el problema.
Rahil Wazir
su respuesta reemplace un elemento de la matriz por otro NO para eliminar un elemento
ahmed hamdy
Voto a favor. Esta respuesta no proporciona el resultado esperado. Por favor, elimine esta respuesta incorrecta.
mickmackusa