juanlemon
¿Cuál es una forma elegante de eliminar un objeto de una matriz de objetos en PHP?
class Data{
private $arrObservers;
public add(Observer $o) {
array_push($this->arrObservers, $o);
}
public remove(Observer $o) {
// I NEED THIS CODE to remove $o from $this->arrObservers
}
}
gordon
Tu puedes hacer
function unsetValue(array $array, $value, $strict = TRUE)
{
if(($key = array_search($value, $array, $strict)) !== FALSE) {
unset($array[$key]);
}
return $array;
}
También puedes usar spl_object_hash
para crear un hash para los objetos y usarlo como clave de matriz.
Sin embargo, PHP también tiene una estructura de datos nativa para colecciones de objetos con SplObjectStorage
:
$a = new StdClass; $a->id = 1;
$b = new StdClass; $b->id = 2;
$c = new StdClass; $c->id = 3;
$storage = new SplObjectStorage;
$storage->attach($a);
$storage->attach($b);
$storage->attach($c);
echo $storage->count(); // 3
// trying to attach same object again
$storage->attach($c);
echo $storage->count(); // still 3
var_dump( $storage->contains($b) ); // TRUE
$storage->detach($b);
var_dump( $storage->contains($b) ); // FALSE
SplObjectStorage
es Traversable
así que puedes foreach
sobre eso también.
En una nota al margen, PHP también tiene interfaces nativas para Sujeto y Observador.
-
+1 ese es el mejor enfoque. Sin mencionar que a partir de PHP 5.3,
SplObjectStorage
implementosArrayAccess
.– Ionus G. Stan
26 de agosto de 2010 a las 8:56
-
Dada la naturaleza de la pregunta, piense si
search_array()
devolucionesfalse
lo mejor que se puede hacer esthrow new OutOfBoundsException("No matching Observer found attached to the subject.")
. Cuando se considera cuidadosamente, sería una situación excepcional para un adjuntoObserver
para no existir mas! 🙂–Anthony Rutledge
11 de febrero de 2021 a las 2:00
icio
Estoy de acuerdo con las respuestas anteriores, pero en aras de la exhaustividad (donde es posible que no tenga ID únicos para usar como clave), mis métodos preferidos para eliminar valores de una matriz son los siguientes:
/**
* Remove each instance of a value within an array
* @param array $array
* @param mixed $value
* @return array
*/
function array_remove(&$array, $value)
{
return array_filter($array, function($a) use($value) {
return $a !== $value;
});
}
/**
* Remove each instance of an object within an array (matched on a given property, $prop)
* @param array $array
* @param mixed $value
* @param string $prop
* @return array
*/
function array_remove_object(&$array, $value, $prop)
{
return array_filter($array, function($a) use($value, $prop) {
return $a->$prop !== $value;
});
}
Los cuales se utilizan de la siguiente manera:
$values = array(
1, 2, 5, 3, 5, 6, 7, 1, 2, 4, 5, 6, 6, 8, 8,
);
print_r(array_remove($values, 6));
class Obj {
public $id;
public function __construct($id) {
$this->id = $id;
}
}
$objects = array(
new Obj(1), new Obj(2), new Obj(4), new Obj(3), new Obj(6), new Obj(4), new Obj(3), new Obj(1), new Obj(5),
);
print_r(array_remove_object($objects, 1, 'id'));
cody snider
Recomiendo usar la ID (si tiene una, cualquier cosa que sea única para ese objeto debería funcionar dentro de lo razonable) del objeto como clave de matriz. De esta manera, puede abordar el objeto dentro de la matriz sin tener que ejecutar un bucle o almacenar la ID en otra ubicación. El código sería algo como esto:
$obj_array[$obj1->getId()] = $obj1;
$obj_array[$obj2->getId()] = $obj2;
$obj_array[$obj3->getId()] = $obj3;
unset($obj_array[$object_id]);
ACTUALIZAR:
class Data{
private $arrObservers;
public add(Observer $o) {
$this->arrObservers[$o->getId()] = $o;
}
public remove(Observer $o) {
unset($this->arrObservers[$o->getId()]);
}
}
-
Sin embargo, necesitará un método getId() para el objeto Observer.
– Cody Snider
26 de agosto de 2010 a las 8:49
unset($myArray[$index]);
dónde $index
es el índice del elemento que desea eliminar. Si no desea una respuesta más específica, muestre algún código o describa lo que está tratando de hacer.
$obj_array['obj1'] = $obj1;
$obj_array['obj2'] = $obj2;
$obj_array['obj3'] = $obj3;
unset($obj_array['obj3']);
-
-1 porque OP da objeto a la función, no a la clave y, por lo tanto, este ejemplo está incompleto.
– Mikulas Dite
27 de agosto de 2010 a las 8:58
Para quitar un objeto de un multi dimensional array
puedes usar esto:
$exampleArray= [
[
"myKey"=>"This is my key",
"myValue"=>"10"
],
[
"myKey"=>"Oh!",
"myValue"=>"11"
]
];
Con array_column
puede especificar el nombre de su columna clave:
if(($key = array_search("Oh!", array_column($exampleArray, 'myKey'))) !== false) {
unset($exampleArray[$key]);
}
Y esto eliminará el objeto indicado.
-
-1 porque OP da objeto a la función, no a la clave y, por lo tanto, este ejemplo está incompleto.
– Mikulas Dite
27 de agosto de 2010 a las 8:58
hielo delgado
Use esto para su almacenamiento interno de objetos en su lugar: http://us2.php.net/manual/en/class.splobjectstorage.php