web-dev-qa-db-ja.com

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
  }  

}
30
danidacar

できるよ

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

SplObjectStorageTraversableであるため、foreachも同様に上書きできます。

傍注では、PHPには Subject および Observer のネイティブインターフェイスもあります。

48
Gordon

上記の答えには同意しますが、完全性のために(キーとして使用する一意の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'));

お役に立てば幸いです。

14
icio

配列キーとして、オブジェクトのID(もしあれば、そのオブジェクトに固有のものは合理的に機能するはずです)を使用することをお勧めします。これにより、ループを実行したり、IDを別の場所に保存したりすることなく、配列内のオブジェクトをアドレス指定できます。コードは次のようになります。

$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
Cody Snider

unset($myArray[$index]); where $indexは、削除する要素のインデックスです。より具体的な回答が必要ない場合は、コードを表示するか、やろうとしていることを説明してください。

3
Tatu Ulmanen
$obj_array['obj1'] = $obj1;
$obj_array['obj2'] = $obj2;
$obj_array['obj3'] = $obj3;
unset($obj_array['obj3']);
3
Alex Pliutau
 function obj_array_clean ($array, $objId)
 {
    $new = array() ;
    foreach($array as $value)
    {
        $new[$value->{$objId}] = $value;
    }
    $array = array_values($new);
    return $array;
 }

 $ext2 = obj_array_clean($ext, 'OnjId');
  • 配列オブジェクト$ arrayから重複オブジェクト「OnjId」を削除します。
0
Softmixt

代わりに、これを内部オブジェクトストレージに使用します。 http://us2.php.net/manual/en/class.splobjectstorage.php

0
thinice

オブジェクトの配列から1つ以上のオブジェクトを削除する場合(spl_object_hashを使用してオブジェクトが同じかどうかを判断する)、このメソッドを使用できます。

$this->arrObservers = Arr::diffObjects($this->arrObservers, [$o]);

from このライブラリ

0
Minwork

multi dimensional arrayからオブジェクトを削除するには、これを使用できます:

$exampleArray= [
    [
      "myKey"=>"This is my key",
      "myValue"=>"10"
    ],
    [
      "myKey"=>"Oh!",
      "myValue"=>"11"
    ]
];

array_columnを使用すると、キー列名を指定できます。

if(($key = array_search("Oh!", array_column($exampleArray, 'myKey'))) !== false) {
    unset($exampleArray[$key]);
}

そして、これは指定されたオブジェクトを削除します。

0
tomloprod