PHP:从数组中删除对象
在PHP中,从对象数组中删除对象的优雅方式是什么 我只是想说清楚PHP:从数组中删除对象,php,arrays,object,Php,Arrays,Object,在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->arrObserv
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
}
}
unset($myArray[$index])
其中$index
是要删除的元素的索引。如果您不想得到更具体的答案,请显示一些代码或描述您正在尝试执行的操作。我建议使用对象的ID(如果您有ID,则该对象唯一的任何内容都应在合理范围内)作为数组键。通过这种方式,您可以在数组中寻址对象,而无需运行循环或将ID存储在其他位置。代码如下所示:
$obj_array['obj1'] = $obj1;
$obj_array['obj2'] = $obj2;
$obj_array['obj3'] = $obj3;
unset($obj_array['obj3']);
$obj_array[$obj1->getId()] = $obj1;
$obj_array[$obj2->getId()] = $obj2;
$obj_array[$obj3->getId()] = $obj3;
unset($obj_array[$object_id]);
更新:
class Data{
private $arrObservers;
public add(Observer $o) {
$this->arrObservers[$o->getId()] = $o;
}
public remove(Observer $o) {
unset($this->arrObservers[$o->getId()]);
}
}
你能行
function unsetValue(array $array, $value, $strict = TRUE)
{
if(($key = array_search($value, $array, $strict)) !== FALSE) {
unset($array[$key]);
}
return $array;
}
还可以使用为对象创建哈希并将其用作数组键
但是,PHP还具有对象集合的本机数据结构,包括:
SplObjectStorage
是可遍历的,因此您也可以对其进行foreach
另一方面,PHP还有用于和的本机接口。我同意上述答案,但为了完整性(您可能没有唯一的ID用作键),我首选的从数组中删除值的方法如下:
/**
* 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;
});
}
以以下方式使用:
$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'));
希望能有所帮助。我相信这是最好的办法
$index = array_search($o, $this->arrObservers, true);
unset($this->arrObservers[$index]);
试试这个,会解决你的问题
class Data{
private $arrObservers;
public add(Observer $o) {
array_push($this->arrObservers,$o);
}
public remove($Observer $o) {
unset($this->arrObservers[$o]);
}
}
将其用于内部对象存储:
- 它将从array objects$array中删除重复的对象“OnjId”
$exampleArray= [
[
"myKey"=>"This is my key",
"myValue"=>"10"
],
[
"myKey"=>"Oh!",
"myValue"=>"11"
]
];
使用array\u column
可以指定键列名:
if(($key = array_search("Oh!", array_column($exampleArray, 'myKey'))) !== false) {
unset($exampleArray[$key]);
}
这将删除指定的对象。如果要从对象数组中删除一个或多个对象(使用spl\u object\u hash确定对象是否相同),可以使用以下方法:
$this->arrObservers = Arr::diffObjects($this->arrObservers, [$o]);
从。阅读GoF手册的观察者模式部分?这里有一个解决方案,它将消除为查找要删除的对象的索引而进行昂贵搜索的需要
public function addObserver(string $aspect, string $viewIndex, Observer $view)
{
$this->observers[$aspect][$viewIndex] = $view;
}
public function removeObserver(string $aspect, string $viewIndex)
{
if (!isset($this->observers[$aspect])) {
throw new OutOfBoundsException("No such aspect ({$aspect}) of this Model exists: " . __CLASS__);
}
if (!isset($this->observers[$aspect][$viewIndex])) {
throw new OutOfBoundsException("No such View for ({$viewIndex}) was added to the aspect ({$aspect}) of this Model:" . __CLASS__);
}
unset($this->observers[$aspect][$viewIndex]);
}
如果不使用跟踪特定的模型更新了哪些视图
,则可能会丢失“方面”维度
public function addObserver(string $viewIndex, Observer $view)
{
$this->observers[$viewIndex] = $view;
}
public function removeObserver(string $viewIndex)
{
if (!isset($this->observers[$viewIndex])) {
throw new OutOfBoundsException("No such View for ({$viewIndex}) was added to this Model:" . __CLASS__);
}
unset($this->observers[$viewIndex]);
}
摘要
在将对象指定给数组之前,以查找元素的方式进行构建。否则,您必须首先发现对象元素的索引
如果您有大量的对象元素(甚至不止一个),那么您可能需要首先找到对象的索引。PHP函数array\u search()
是一种从值开始并获取索引/键的方法
调用函数时,一定要使用strict
参数
如果第三个参数strict设置为true
,则数组_search()
函数将在干草堆中搜索相同的元素。这
这意味着它还将执行针的严格类型比较
haystack和对象必须是同一个实例
这是可以的,但是如何查找对象的索引呢?通过数组中的值进行搜索?@daniphp您可以将对象与===进行比较。我想您的意思是array\u push($this->arobserver,$o)
?对于Data::add(),$this->Observer[]=$o
,效率要高得多。不过,您需要一个getId()方法来处理Observer对象。+1这是最好的方法。更不用说,从PHP5.3开始,SplObjectStorage
实现了ArrayAccess
。我建议使用如果($key=array\u search($value,$array,$strict))!==false)
cuz0==false
@Anpher good call。固定的。虽然我真的认为如果只有对象要处理,OP应该使用SplObjectStorage。投票支持SplObjectStorage的引用-这正是我需要的。SplObjectStorage!这是最好的方法Array\u push将分配一个数字键,因此您不会找到$o作为键,即使数组可以使用对象作为键-1,因为OP将对象指定给函数,而不是键,因此此示例不完整。
public function addObserver(string $aspect, string $viewIndex, Observer $view)
{
$this->observers[$aspect][$viewIndex] = $view;
}
public function removeObserver(string $aspect, string $viewIndex)
{
if (!isset($this->observers[$aspect])) {
throw new OutOfBoundsException("No such aspect ({$aspect}) of this Model exists: " . __CLASS__);
}
if (!isset($this->observers[$aspect][$viewIndex])) {
throw new OutOfBoundsException("No such View for ({$viewIndex}) was added to the aspect ({$aspect}) of this Model:" . __CLASS__);
}
unset($this->observers[$aspect][$viewIndex]);
}
public function addObserver(string $viewIndex, Observer $view)
{
$this->observers[$viewIndex] = $view;
}
public function removeObserver(string $viewIndex)
{
if (!isset($this->observers[$viewIndex])) {
throw new OutOfBoundsException("No such View for ({$viewIndex}) was added to this Model:" . __CLASS__);
}
unset($this->observers[$viewIndex]);
}