Rimozione dell'elemento dell'array per valore


166

Devo rimuovere l'elemento dell'array con un determinato valore:

if (in_array($id, $items)) {
    $items = array_flip($items);
    unset($items[ $id ]);
    $items = array_flip($items);
}

Potrebbe essere fatto in modo più breve (più efficiente)?


Risposte:


423

Può essere realizzato con una semplice fodera.

Avere questo array:

$arr = array('nice_item', 'remove_me', 'another_liked_item', 'remove_me_also');

Tu puoi fare:

$arr = array_diff($arr, array('remove_me', 'remove_me_also'));

E il valore di $arrsarà:

array('nice_item', 'another_liked_item')

Spero che aiuti a scrivere un bellissimo codice.


2
No, non funziona con array di riferimento, la array_difffunzione è non distruttiva, restituisce un nuovo array.
Alejandro García Iglesias,

2
@srcspider perché no? $referenced = array_diff($referenced, $items_to_remove);
Alejandro García Iglesias,

1
$ referenced ora punta a un nuovo array, l'array che si desidera modificare ha ancora i vecchi valori.
srcspider,

2
@srcspider bene, dimmi cosa sta succedendo qui allora ... codepad.org/11ZhiFP0
Alejandro García Iglesias

1
colpa mia; L'espediente di aliasing variabile di php mi fa sempre inciampare>.>
srcspider

37

Sto aggiungendo una seconda risposta. Ho scritto uno script di benchmark rapido per provare vari metodi qui.

$arr = array(0 => 123456);
for($i = 1; $i < 500000; $i++) {
    $arr[$i] = rand(0,PHP_INT_MAX);
}

shuffle($arr);
$arr2 = $arr;
$arr3 = $arr;

/** 
 * Method 1 - array_search()
 */
$start = microtime(true);
while(($key = array_search(123456,$arr)) !== false) {
    unset($arr[$key]);
}
echo count($arr). ' left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 2 - basic loop
 */
$start = microtime(true);
foreach($arr2 as $k => $v) {
    if ($v == 123456) {
        unset($arr2[$k]);
    }
}
echo count($arr2). 'left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 3 - array_keys() with search parameter
 */
$start = microtime(true);
$keys = array_keys($arr3,123456);
foreach($keys as $k) {
    unset($arr3[$k]);
}
echo count($arr3). 'left, in '.(microtime(true) - $start).' seconds<BR>';

Il terzo metodo, array_keys()con il parametro di ricerca facoltativo specificato, sembra essere di gran lunga il metodo migliore. Esempio di output:

499999 left, in 0.090957164764404 seconds
499999left, in 0.43156313896179 seconds
499999left, in 0.028877019882202 seconds

A giudicare da ciò, la soluzione che vorrei utilizzare sarebbe:

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}

Penso che array_search sia un codice molto più leggibile rispetto all'utilizzo del metodo array_diff. Upvote
kendepelchin,

@zombat Mi chiedo se l'ordine abbia a che fare con i risultati. È possibile che shuffle metta il valore che stiamo cercando o più vicino al fronte o alla fine. Diverso da quello ... +1
Generale Redneck,

31

Che ne dite di:

if (($key = array_search($id, $items)) !== false) unset($items[$key]);

o per più valori:

while(($key = array_search($id, $items)) !== false) {
    unset($items[$key]);
}

Ciò impedirebbe anche la perdita di chiave, il che è un effetto collaterale di array_flip().


1
non funzionerà se $ id è il primo elemento dell'array, meglio così: if (($ key = array_search ($ id, $ items))! == false) unset ($ items [$ key]);
Marek,

15

per rimuovere $rm_valda$arr

unset($arr[array_search($rm_val, $arr)]);

8

La soluzione più potente sarebbe utilizzare array_filter, che consente di definire la propria funzione di filtro.

Ma alcuni potrebbero dire che è un po 'eccessivo, nella tua situazione ...
Un semplice foreachciclo per passare attraverso l'array e rimuovere l'elemento che non vuoi dovrebbe essere sufficiente.

Qualcosa del genere, nel tuo caso, dovrebbe probabilmente fare il trucco:

foreach ($items as $key => $value) {
    if ($value == $id) {
        unset($items[$key]);
        // If you know you only have one line to remove, you can decomment the next line, to stop looping
        //break;
    }
}

6

3
Ho appena letto la documentazione e mi consiglia di utilizzare array_keys () per trovare tutte le chiavi associate a un valore.
Savageman,

@Savageman - Concordato. Ho eseguito un benchmark rapido e array_keys()sembra avere prestazioni migliori rispetto array_search()a questo compito.
Zombat,

6

Le tue soluzioni funzionano solo se hai valori univoci nel tuo array

Vedere:

<?php
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
?>

Un modo migliore sarebbe disinserito con array_search , in un ciclo se necessario.


hai ragione, ma in questo caso particolare sono abbastanza sicuro che i valori siano unici :)
Marek,

5

senza vibrazione:

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}

5
function deleteValyeFromArray($array,$value)
{
   foreach($array as $key=>$val)
   {
      if($val == $value)
      {
         unset($array[$key]);
      }
   }
   return $array;
}

4

È possibile utilizzare la funzione array_splice per questa operazione Rif: array_splice

array_splice($array, array_search(58, $array ), 1);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.