对象的array_unique?

Joh*_*nes 73 php arrays methods

是否有像array_unique这样的对象方法?我有一堆带有'Role'对象的数组,我合并了,然后我想取出重复项:)

Mat*_*oli 136

array_unique使用SORT_REGULAR以下对象来处理对象数组:

class MyClass {
    public $prop;
}

$foo = new MyClass();
$foo->prop = 'test1';

$bar = $foo;

$bam = new MyClass();
$bam->prop = 'test2';

$test = array($foo, $bar, $bam);

print_r(array_unique($test, SORT_REGULAR));
Run Code Online (Sandbox Code Playgroud)

将打印:

Array (
    [0] => MyClass Object
        (
            [prop] => test1
        )

    [2] => MyClass Object
        (
            [prop] => test2
        )
)
Run Code Online (Sandbox Code Playgroud)

请在此处查看:http://3v4l.org/VvonH#v529

警告:它将使用"=="比较,而不是严格比较("===").

因此,如果要删除对象数组中的重复项,请注意它将比较每个对象属性,而不是比较对象标识(实例).

  • 这个答案比接受的答案要好得多.然而,由于`$ bam-> prop ='test2',`(应该是''test1'),这个例子没有显示值('==`)或身份(`===`)的比较.展示差异).有关示例,请参见http://codepad.viper-7.com/8NxWhG. (11认同)
  • 小心用 array_unique() 比较对象,该函数将应用深度比较,如果涉及太多递归,可能会导致服务器崩溃——我正在看你的 Doctrine 实体。更好地确定您的对象的独特之处,并用它来索引您的对象。例如,如果您的对象有一个字符串标识符,请使用该标识符作为键构建一个数组。 (2认同)

Fel*_*ing 88

好吧,array_unique()比较元素的字符串值:

注意:当且仅(string) $elem1 === (string) $elem2当字符串表示相同时,才使用两个元素相等,将使用第一个元素.

因此,请确保__toString()在您的类中实现该方法,并为相等的角色输出相同的值,例如

class Role {
    private $name;

    //.....

    public function __toString() {
        return $this->name;
    }

}
Run Code Online (Sandbox Code Playgroud)

如果它们具有相同的名称,则会将两个角色视为相等.

  • @Jacob因为`array_unique`和`__toString()`都没有比较.`__toString()`定义了在字符串上下文中使用时对象实例的行为方式,`array_unique`返回删除了重复值的输入数组.它只是*在内部使用*比较. (2认同)
  • 向所有对象添加`__toString()`方法比在array_unique中添加`SORT_REGULAR`标志要痛苦得多,请参阅Matthieu Napoli他的回答.除了`__toString()`方法还有许多其他用例然后用于对象比较,所以这甚至是不可能的. (2认同)

sal*_*the 28

我知道已经有了一个公认的答案,但这里有另一种选择.

与之前的答案相反,它使用,in_array()因为PHP 5 中比较对象的性质允许我们这样做.利用此对象比较行为要求数组包含对象,但这似乎就是这种情况.

$merged = array_merge($arr, $arr2);
$final  = array();

foreach ($merged as $current) {
    if ( ! in_array($current, $final)) {
        $final[] = $current;
    }
}

var_dump($final);
Run Code Online (Sandbox Code Playgroud)

  • `in_array` 应该使用 `$strict` 参数!否则,您可以使用“==”而不是“===”来比较对象。更多这里:http://fr2.php.net/manual/fr/function.in-array.php (2认同)
  • *不*使用严格参数是这里故意的选择。我想找到“相等”的对象,不一定是对象的“相同实例”。答案中提到的链接对此进行了解释,其中说:“*当使用比较运算符(==)时,对象变量以简单的方式进行比较,即:如果两个对象实例具有相同的属性和值,则它们相等, 和 是同一类的实例。*” (2认同)

yan*_*kee 15

这是一种删除数组中重复对象的方法:

<?php
// Here is the array that you want to clean of duplicate elements.
$array = getLotsOfObjects();

// Create a temporary array that will not contain any duplicate elements
$new = array();

// Loop through all elements. serialize() is a string that will contain all properties
// of the object and thus two objects with the same contents will have the same
// serialized string. When a new element is added to the $new array that has the same
// serialized value as the current one, then the old value will be overridden.
foreach($array as $value) {
    $new[serialize($value)] = $value;
}

// Now $array contains all objects just once with their serialized version as string.
// We don't care about the serialized version and just extract the values.
$array = array_values($new);
Run Code Online (Sandbox Code Playgroud)


小智 8

您还可以先序列化:

$unique = array_map( 'unserialize', array_unique( array_map( 'serialize', $array ) ) );
Run Code Online (Sandbox Code Playgroud)

从PHP 5.2.9开始,您可以使用可选sort_flag SORT_REGULAR:

$unique = array_unique( $array, SORT_REGULAR );
Run Code Online (Sandbox Code Playgroud)


小智 8

如果要根据特定属性过滤对象,也可以使用它们的array_filter函数:

//filter duplicate objects
$collection = array_filter($collection, function($obj)
{
    static $idList = array();
    if(in_array($obj->getId(),$idList)) {
        return false;
    }
    $idList []= $obj->getId();
    return true;
});
Run Code Online (Sandbox Code Playgroud)


Sil*_*ght 6

从这里:http://php.net/manual/en/function.array-unique.php#75307

这个也适用于对象和数组.

<?php
function my_array_unique($array, $keep_key_assoc = false)
{
    $duplicate_keys = array();
    $tmp         = array();       

    foreach ($array as $key=>$val)
    {
        // convert objects to arrays, in_array() does not support objects
        if (is_object($val))
            $val = (array)$val;

        if (!in_array($val, $tmp))
            $tmp[] = $val;
        else
            $duplicate_keys[] = $key;
    }

    foreach ($duplicate_keys as $key)
        unset($array[$key]);

    return $keep_key_assoc ? $array : array_values($array);
}
?>
Run Code Online (Sandbox Code Playgroud)