2010-01-05 23 views
50

Tengo un bucle foreach configurado para recorrer mi matriz, verificar si hay un determinado enlace y, si lo encuentra, elimina ese enlace de la matriz.Desarreglando valores de matriz en un bucle foreach

Mi código:

foreach($images as $image) 
{ 
    if($image == 'http://i27.tinypic.com/29yk345.gif' || 
    $image == 'http://img3.abload.de/img/10nx2340fhco.gif' || 
    $image == 'http://i42.tinypic.com/9pp2456x.gif') 
    { 
     unset($images[$image]); 
    } 
} 

Pero no elimina los entires matriz. Probablemente tenga algo que ver con $images[$image], ya que esa no es la clave de la entrada de la matriz, ¿solo el contenido? ¿Hay alguna manera de hacer esto sin incorporar un contador?

Gracias.

EDITAR: Gracias chicos, pero ahora tengo otro problema donde las entradas de la matriz realmente no se eliminan.

Mi nuevo código:

foreach($images[1] as $key => $image) 
{ 
    if($image == 'http://i27.tinypic.com/29yk345.gif') 
    $image == 'http://img3.abload.de/img/10nx2340fhco.gif' || 
    $image == 'http://i42.tinypic.com/9pp2456x.gif') 
    { 
     unset($images[$key]); 
    } 
} 

$ imágenes es actuallty una matriz bidimensional ahora, por tanto, por lo que necesito $ imágenes [1]. Lo he comprobado y funciona con éxito alrededor de los elementos de la matriz, y algunos elementos realmente tienen algunas de esas URL que deseo eliminar, pero no se eliminan. Esta es mi matriz $images:

Array 
(
    [0] => Array 
     (
      [0] => useless 
      [1] => useless 
      [2] => useless 
      [3] => useless 
      [4] => useless 
     ) 

    [1] => Array 
     (
      [0] => http://i27.tinypic.com/29yk345.gif 
      [1] => http://img3.abload.de/img/10nx2340fhco.gif 
      [2] => http://img3.abload.de/img/10nx2340fhco.gif 
      [3] => http://i42.tinypic.com/9pp2456x.gif 
     ) 

) 

Gracias!

+2

También sugeriría si (in_array ($ image, array ('http://i27.tinypic.com/29yk345.gif', 'http://img3.abload.de/img/10nx2340fhco.gif', 'http://i42.tinypic.com/9pp2456x.gif')). Lo hace más legible;) –

+2

Como modificó la matriz que está iterando, eso debe reflejarse en su llamada para desarmar: unset ($ images [1] [$ clave]); – bish

+0

Y los paréntesis en la instrucción if son incorrectos, pero supongo que esto solo es un error (de lo contrario recibiría un mensaje de error) –

Respuesta

71
foreach($images as $key => $image) 
{ 
    if(in_array($image, array(
     'http://i27.tinypic.com/29ykt1f.gif', 
     'http://img3.abload.de/img/10nxjl0fhco.gif', 
     'http://i42.tinypic.com/9pp2tx.gif', 
    )) 
    { 
     unset($images[$key]); 
    } 
} 
+0

Gracias por la ayuda, pero estoy teniendo problemas para eliminar algunos de los elementos de la matriz. Ver la edición en la primera publicación :) – Matt

+6

Luego intente' unset ($ images [1] [$ key]);.. ' – hsz

4

$image es en su caso, el valor del artículo y no la clave. Utilice la siguiente sintaxis para obtener la clave también:

foreach ($images as $key => $value) { 
    /* … */ 
} 

Ahora puede eliminar el elemento con unset($images[$key]).

+0

Esto podría funcionar, pero todavía copiará todo el conjunto para ejecutar el bucle foreach Así que es una pérdida de memoria Si no me equivoco, el enfoque de referencias (véase mi respuesta) es también más rápido que . resolución de la clave/valor par cada vez que el desarmado sucede – selfawaresoup

+0

la segunda parte es en realidad no es tan cierto momento desarmado hace referencia, por supuesto, no funciona – selfawaresoup

+0

@Techpriester:... 'foreach' siempre funciona en una copia interna – Gumbo

1

foreach($images as $key=>$image)         
{    
    if($image == 'http://i27.tinypic.com/29ykt1f.gif' ||  
    $image == 'http://img3.abload.de/img/10nxjl0fhco.gif' ||  
    $image == 'http://i42.tinypic.com/9pp2tx.gif')  
    { unset($images[$key]); }        
} 

!! foreach imágenes ($ imagen => $ $ clave como

imagen causa $ es el valor, por lo que las imágenes $ [$] imagen no tienen sentido

+2

Formato. su código por favor :) –

+0

Fail. Debería usar 'code sample' - not' blockquote'.;) – hsz

47

Trate de que:

.
foreach ($images as $key => &$image) { 
    if (yourConditionGoesHere) { 
     unset($images[$key]) 
    } 
} 

Normalmente, foreach funciona con una copia de la matriz por lo que cualquier cambio que realice, están hechos a dicha copia y no afectan a la matriz real.

Por lo tanto, debe deshacer los valores mediante $ images [$ key];

La referencia en & $ imagen evita que el bucle cree una copia de la matriz que desperdiciará memoria.

+0

Gracias. Creo que lo que está diciendo está relacionado a mi problema (ver edición). Incluso si agrego un '&' aunque todavía no funciona. – Matt

+9

"La referencia en & $ image evita que el bucle cree una copia de la matriz que desperdiciará memoria". <- lo que estaba buscando :) – marcovtwout

+1

Después del ciclo deberías 'desarmar ($ image);'. –

1

Una solución sería utilizar la clave de sus elementos para eliminarlos: puede usar las claves y los valores al realizar un bucle con foreach.

Por ejemplo:

$arr = array(
    'a' => 123, 
    'b' => 456, 
    'c' => 789, 
); 

foreach ($arr as $key => $item) { 
    if ($item == 456) { 
     unset($arr[$key]); 
    } 
} 

var_dump($arr); 

le dará esta matriz, al final:


Lo que significa que, en su caso, algo como esto debe hacer el truco:

foreach($images as $key => $image) 
{ 
    if($image == 'http://i27.tinypic.com/29yk345.gif' || 
    $image == 'http://img3.abload.de/img/10nx2340fhco.gif' || 
    $image == 'http://i42.tinypic.com/9pp2456x.gif') 
    { 
     unset($images[$key]); 
    } 
} 
0

Perdón por la respuesta tardía, recientemente tuve el mismo profesional blem con PHP y descubrió que cuando se trabaja con matrices que no usan la estructura $key => $value, cuando se usa el ciclo foreach, se copia el valor real de la posición en la variable de ciclo, en este caso $image. Intenta usar este código y solucionará tu problema.

for ($i=0; $i < count($images[1]); $i++) 
{ 

    if($images[1][$i] == 'http://i27.tinypic.com/29yk345.gif' || 

    $images[1][$i] == 'http://img3.abload.de/img/10nx2340fhco.gif' || 

    $images[1][$i] == 'http://i42.tinypic.com/9pp2456x.gif') 

    { 

     unset($images[1][$i]); 

    } 

} 

var_dump($images);die(); 
2

También se necesita un

$i--; 

después de cada desarmar a no omitir un elemento/

Porque cuando saques tu $item[45], el siguiente elemento en el bucle de debe ser $item[45] - que era [46] antes de desarmar. Si no lo hicieras, siempre saltearías un elemento después de desactivarlo.

+3

Pero unset() no va a cambiar el índice de matriz, así que no creo que esto $ yo-- yo s necesario aquí. Si se usa el método array_splice(), los elementos se desplazarán para cubrir el agujero eliminado y $ i-- es necesario. –

3

Puede usar el índice del elemento de matriz para eliminarlo de la matriz, la próxima vez que use la variable $list, verá que la matriz ha cambiado.

Pruebe algo como esto

foreach($list as $itemIndex => &$item) { 

    if($item['status'] === false) { 
     unset($list[itemIndex]); 
    } 

} 
+0

Esto no funciona, ver a continuación. http://stackoverflow.com/a/2008893/922522 – Justin

+0

Consulte este método aquí: http://ideone.com/Vv4DR8 – Justin

+0

@ Justin que se debe a que está desactivando $ artículo en lugar del artículo de la lista. Bifurqué tu código, y esto funciona: http://ideone.com/SY0XC3 – rolandow

3

Para responder a la pregunta inicial (después de su edición), es necesario desarmar ($ imágenes [1] [$ key]);

Ahora más información sobre cómo funciona PHP: Puede desconectar con seguridad los elementos de la matriz en el bucle foreach, y no importa si tiene & o no para el elemento de la matriz. Ver este código:

$a=[1,2,3,4,5]; 
foreach($a as $key=>$val) 
{ 
    if ($key==3) unset($a[$key]); 
} 
print_r($a); 

Esta impresora:

Array 
(
    [0] => 1 
    [1] => 2 
    [2] => 3 
    [4] => 5 
) 

Así como se puede ver, si usted lo correcto desarmado dentro del bucle foreach, todo funciona bien.

Cuestiones relacionadas