PHP: Удалить объект из массива

Каков элегантный способ удаления объекта из массива объектов в 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
  }  

}
31
задан luiges90 31 October 2012 в 02:48
поделиться

7 ответов

Вы можете сделать

function unsetValue(array $array, $value, $strict = TRUE)
{
    if(($key = array_search($value, $array, $strict)) !== FALSE) {
        unset($array[$key]);
    }
    return $array;
}

Вы также можете использовать spl_object_hash , чтобы создать хэш для объектов и использовать его в качестве ключа массива.

Однако в PHP также есть собственная структура данных для коллекций объектов с 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 является Traversable, так что вы можете foreach над этим тоже.

Кстати, в PHP также есть собственные интерфейсы для Subject и Observer.

50
ответ дан 27 November 2019 в 21:52
поделиться

Я рекомендую использовать идентификатор (если он у вас есть, все, что будет уникальным для этого объекта, должно работать в разумных пределах) объекта в качестве ключа массива. Таким образом, вы можете обратиться к объекту в массиве без необходимости запускать цикл или сохранять идентификатор в другом месте. Код будет выглядеть примерно так:

$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()]);
  }  

}
6
ответ дан 27 November 2019 в 21:52
поделиться

Я согласен с приведенными выше ответами, но для полноты картины (где у вас может не быть уникальных идентификаторов для использовать в качестве ключа) мои предпочтительные методы удаления значений из массива следующие:

/**
 * 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'));

Надеюсь, это поможет.

15
ответ дан 27 November 2019 в 21:52
поделиться
$obj_array['obj1'] = $obj1;
$obj_array['obj2'] = $obj2;
$obj_array['obj3'] = $obj3;
unset($obj_array['obj3']);
3
ответ дан 27 November 2019 в 21:52
поделиться

Я считаю, что это лучший способ

$index = array_search($o, $this->arrObservers, true);

unset($this->arrObservers[$index]);
-2
ответ дан 27 November 2019 в 21:52
поделиться

unset($myArray[$index]); где $index — индекс элемента, который вы хотите удалить. Если вам не нужен более конкретный ответ, покажите код или опишите, что вы пытаетесь сделать.

3
ответ дан 27 November 2019 в 21:52
поделиться

Попробуйте, это решит вашу проблему.

class Data{
  private $arrObservers;

  public add(Observer $o) {  
    array_push($this->arrObservers,$o);  
  }    

  public remove($Observer $o) {  
    unset($this->arrObservers[$o]);  
  }  
}
-1
ответ дан 27 November 2019 в 21:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: