PHP in_array 对象比较?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17231925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 12:32:53  来源:igfitidea点击:

PHP in_array object comparing?

php

提问by gorgi93

Can the in_arrayfunction compare objects?

在能in_array功能比较的对象?

For example, I have an array of objects and I want to add them distinctly to another array. Is it possible to check if an object has already been added like so:

例如,我有一个对象数组,我想将它们明显地添加到另一个数组中。是否可以像这样检查对象是否已添加:

in_array($distinct, $object);

or is there any other way?

或者还有其他方法吗?

采纳答案by ukliviu

The in_arrayfunction cannot compare objects.

in_array功能无法比较的对象。

You should create unique key-value pairs from your objects and only need to compare those keys when inserting a new object into your final array.

您应该从对象创建唯一的键值对,并且只需要在将新对象插入最终数组时比较这些键。

Assuming that each object has an unique idproperty, a possible solution would be:

假设每个对象都有一个唯一的id属性,一个可能的解决方案是:

$unique_objects = array();

// $data represents your object collection
foreach ($data as $item) {
    if (!array_key_exists($item->id, $unique_objects)) {
        $unique_objects[$item->id] = $obj;
    }
}

回答by Alain Tiemblo

You can use strict comparison:

您可以使用严格比较:

in_array($object, $array, TRUE);

Usage example:

用法示例:

$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); //

回答by smassey

See http://php.net/manual/en/function.spl-object-hash.php

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

Cheers

干杯

回答by Kristofer Doman

There's numerous ways you can do this as you can see. I just thought I would add another one. I don't know why, but when working with object arrays I like to use the array functions which use callbacks.

如您所见,您可以通过多种方式执行此操作。我只是想我会添加另一个。我不知道为什么,但是在处理对象数组时,我喜欢使用使用回调的数组函数。

If your objects have any sort of identifier, which they should if you want to test them for duplication, the following will work:

如果您的对象有任何类型的标识符,如果您想测试它们是否重复,它们应该这样做,以下将起作用:

$found = array_filter($uniqueObjects, function($uniqueObject) use ($object) {
    return $uniqueObject->id == $object->id
});

if (!$found) {
    $uniqueObjects[] = $object;
}

$objectis the object you're looking for, and $uniqueObjectsis the array of objects you're searching to see if it exists. Just match uniqueObject and object on an identifying property, such as an id.

$object是您要查找的对象,$uniqueObjects是您正在搜索以查看它是否存在的对象数组。只需在标识属性上匹配 uniqueObject 和 object,例如id.

回答by Daan

I did some tests comparing objects with the in_arrayfunction. This is my conclusion:

我做了一些比较对象和in_array函数的测试。这是我的结论:

When you try to find the same instance of an objectin an array (like OP), then in_arraycould work with the strict comparison boolean set.

当您尝试在数组(如 OP)中查找对象相同实例时in_array可以使用严格比较布尔集。

When you try to find any object of the same class but with a different instance, in_arrayshows counter-intuitive behavior.

当您尝试查找同一类但具有不同实例的任何对象时,会in_array表现出违反直觉的行为。

There is a great user comment on PHP.netabout the counter-intuitive edge cases.

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
// 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

As you can see that without strict checking the in_arraytests 4 - 7 don't make sense.

正如您所看到的,如果不严格检查in_array测试 4 - 7 是没有意义的。

We know from PHP.netthat two objects are onlythe same in strict comparison (===) when they are from the same class + instance. Two objects are alreadythe same in loose comparison (==) when they are from the same class.

我们从 PHP.net 知道,两个对象只有在严格比较 ( ===) 时来自同一个类 + 实例才相同。两个物体已经在松散的比较(相同==)时,他们都来自同一类。

I wrote some tests with objects to see what happens.

我用对象写了一些测试来看看会发生什么。

$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 the last checks in_arraychecks 3 - 6 give counter-intuitive results.

在最后的检查中,in_array检查 3 - 6 给出了违反直觉的结果。

The reason is as follow. If you try to find any object with a certain value, you are forced to use loose comparison (because when the class is not the same, strict comparison always fails). But due to PHP's variable types, in the last tests these checks are considered true, because the value is considered truthy. Also note that the key on the object is ignored in loose comparison.

原因如下。如果你试图找到任何具有某个值的对象,你就被迫使用松散比较(因为当类不相同时,严格比较总是失败)。但是由于PHP 的变量类型,在最后的测试中这些检查被认为是真的,因为值被认为是真的。另请注意,在松散比较中忽略对象上的键。

回答by Wouter Thielen

I don't know if it is because of a newer PHP version, but in my project, using PHP 5.3.16 on Ubuntu 12.04, it worked. It found the needle object in my array of objects. I have also double-checked by loading a different object of the same class, and testing it against the array contents which did not contain that object, and it returned false indeed.

我不知道是不是因为较新的 PHP 版本,但在我的项目中,在 Ubuntu 12.04 上使用 PHP 5.3.16,它起作用了。它在我的对象数组中找到了针对象。我还通过加载同一类的不同对象进行了双重检查,并针对不包含该对象的数组内容对其进行了测试,结果确实返回了 false。

So yes, in_arraycan compare objects.

所以是的,in_array可以比较对象。

回答by Kremnari

I've come up with a somewhat different, I think more robust, option.

我想出了一个有点不同的,我认为更强大的选项。

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);
}

The benefit to this solution, is it includes a user definable callback to handle collisions. When your adding unique objects, you may want to preserve properties from both the old and the new object.

这个解决方案的好处是它包括一个用户可定义的回调来处理冲突。添加唯一对象时,您可能希望保留旧对象和新对象的属性。

The callback, which can be an anonymous function, receives both the new object and the existing object so the user can have a custom calculation. Return trueto simply replace the existing object, or return a new object (non-bool) to replace it.

回调可以是一个匿名函数,它同时接收新对象和现有对象,以便用户可以进行自定义计算。返回true以简单地替换现有对象,或返回一个新对象(非布尔值)来替换它。

I do not know the performance of this on large datasets though.

我不知道这在大型数据集上的性能。

回答by Justo

If "STRICT" is "FALSE", the comparison is made by converting in a string the elements. So if you override the __toString magic function, you should be available to compare the objects elements.

如果“STRICT”为“FALSE”,则通过将元素转换为字符串来进行比较。因此,如果您覆盖 __toString 魔术函数,您应该可以比较对象元素。