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

在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
  }  

}
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)
cuz
0==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]);
}