28

in_array関数はオブジェクトを比較できますか?

たとえば、オブジェクトの配列があり、それらを別の配列に個別に追加したいとします。次のように、オブジェクトが既に追加されているかどうかを確認することは可能ですか?

in_array($distinct, $object);

または他の方法はありますか?

4

8 に答える 8

32

厳密な比較を使用できます。

in_array($object, $array, TRUE);

使用例:

$a = new stdClass();
$a->x = 42;

$b = new stdClass();
$b->y = 42;

$c = new stdClass();
$c->x = 42;

$array = array($a,$b);

echo in_array($a, $array, true); // 1
echo in_array($b, $array, true); // 1
echo in_array($c, $array, true); //
于 2015-01-22T21:19:33.850 に答える
17
于 2013-06-21T10:30:11.530 に答える
4

in_arrayオブジェクトと関数を比較するいくつかのテストを行いました。これが私の結論です:

配列内のオブジェクトの同じインスタンス(OP など)を検索しようとするin_arrayと、厳密な比較ブール値セットを使用できます。

同じクラスでインスタンスが異なるオブジェクトを見つけようとすると、in_array直観に反する動作を示します。

PHP.netには、直感に反するエッジ ケースに関する素晴らしいユーザー コメントがあります。

// Example array

$array = array(
    'egg' => true,
    'cheese' => false,
    'hair' => 765,
    'goblins' => null,
    'ogres' => 'no ogres allowed in this array'
);

// Loose checking -- return values are in comments

// First three make sense, last four do not

in_array(null, $array); // true
in_array(false, $array); // true
in_array(765, $array); // true
in_array(763, $array); // true
in_array('egg', $array); // true
in_array('hhh', $array); // true
in_array(array(), $array); // true

// Strict checking

in_array(null, $array, true); // true
in_array(false, $array, true); // true
in_array(765, $array, true); // true
in_array(763, $array, true); // false
in_array('egg', $array, true); // false
in_array('hhh', $array, true); // false
in_array(array(), $array, true); // false

ご覧のとおり、in_arrayテスト 4 ~ 7 を厳密にチェックしないと意味がありません。

PHP.netから、2 つのオブジェクトが同じクラス + インスタンスからのものである場合、厳密な比較 ( ) でのみ同じであることがわかっています。2 つのオブジェクトは、同じクラスに属している場合、緩やかな比較 ( ) ですでに同じです。=====

何が起こるかを見るために、オブジェクトを使ったいくつかのテストを書きました。

$a = new stdClass();                              
$a->egg = true;                                   

$b = new stdClass();                              
$b->cheese = false;                               

$c = new stdClass();                              
$c->hair = 765;                                   

$d = new stdClass();                              
$d->goblins = null;                               

$e = new stdClass();                              
$e->ogres = 'no ogres allowed in this array';     

$array2 = array($a, $b, $c,  $d, $e);         

$e = new stdClass();                                            
$e->egg = null;                                                 

$f = new stdClass();                                            
$f->egg = false;                                                

$g = new stdClass();                                            
$g->egg = 765;                                                  

$h = new stdClass();                                            
$h->egg = 763;                                                  

$i = new stdClass();                                            
$i->egg = 'egg';                                                

$j = new stdClass();                                            
$j->egg = 'hhh';                                                

$k = new stdClass();                                            
$k->egg = array();                                              

in_array($e, $array2, false); // false                
in_array($f, $array2, false); // false                
in_array($g, $array2, false); // true                 
in_array($h, $array2, false); // true                 
in_array($i, $array2, false); // true                 
in_array($j, $array2, false); // true                 
in_array($k, $array2, false); // false                

in_array($e, $array2, true); // false                 
in_array($f, $array2, true); // false                 
in_array($g, $array2, true); // false                 
in_array($h, $array2, true); // false                 
in_array($i, $array2, true); // false                 
in_array($j, $array2, true); // false                 
in_array($k, $array2, true); // false 

最後のチェックでは、in_arrayチェック 3 ~ 6 で直観に反する結果が得られます。

その理由は以下の通りです。特定の値を持つオブジェクトを見つけようとすると、緩やかな比較を使用する必要があります (クラスが同じでない場合、厳密な比較は常に失敗するため)。しかし、PHP の変数の型により、最後のテストでは、値が真であると見なされるため、これらのチェックは真と見なされます。また、緩やかな比較ではオブジェクトのキーが無視されることに注意してください。

于 2019-05-03T08:40:54.830 に答える
3

http://php.net/manual/en/function.spl-object-hash.phpを参照してください。

if ( ! array_key_exists( spl_object_hash( $obj ), $objects ) ) {
    $objects[ spl_object_hash( $obj ) ] = $obj;
}

乾杯

于 2013-06-21T09:58:14.517 に答える
1

新しい PHP バージョンが原因かどうかはわかりませんが、私のプロジェクトでは、Ubuntu 12.04 で PHP 5.3.16 を使用して動作しました。オブジェクトの配列に針オブジェクトが見つかりました。また、同じクラスの別のオブジェクトをロードし、そのオブジェクトを含まない配列の内容に対してテストすることで再確認しましたが、実際には false が返されました。

はい、in_arrayオブジェクトを比較できます。

于 2015-02-10T09:18:51.747 に答える
0

私はやや異なる、より堅牢なオプションを考え出しました。

function array_add_unique(&$array, $new, $test, $cb) {
  if(is_array($array) && count($array)>0) {
    for($i = 0; $i < count($array); $i++) {
      if( $array[$i][$test] == $new[$test] ) {
        $do = $cb($array[$i], $new);
        if(is_bool($do) && $do) { $array[$i] = $new; }
        else if(!is_bool($do)) { $array[$i] = $do; }
        return;
      }
    }
  }
  array_push($array, $new);
}

このソリューションの利点は、衝突を処理するためのユーザー定義可能なコールバックが含まれていることです。一意のオブジェクトを追加する場合、古いオブジェクトと新しいオブジェクトの両方のプロパティを保持したい場合があります。

匿名関数であるコールバックは、新しいオブジェクトと既存のオブジェクトの両方を受け取るため、ユーザーはカスタム計算を行うことができます。trueを返して既存のオブジェクトを単純に置き換えるか、新しいオブジェクト (bool 以外) を返して置き換えます。

ただし、大規模なデータセットでのこれのパフォーマンスはわかりません。

于 2015-08-06T15:59:32.990 に答える