php 对象的array_unique?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2426557/
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 06:25:38  来源:igfitidea点击:

array_unique for objects?

phparraysmethods

提问by Johannes

Is there any method like the array_unique for objects? I have a bunch of arrays with 'Role' objects that I merge, and then I want to take out the duplicates :)

有没有像 array_unique 这样的对象方法?我有一堆带有我合并的“角色”对象的数组,然后我想取出重复项:)

回答by Matthieu Napoli

array_uniqueworks with an array of objects using SORT_REGULAR:

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

Will print:

将打印:

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

    [2] => MyClass Object
        (
            [prop] => test2
        )
)

See it in action here: http://3v4l.org/VvonH#v529

在这里查看它的实际效果:http: //3v4l.org/VvonH#v529

Warning: it will use the "==" comparison, not the strict comparison ("===").

警告:它将使用“==”比较,而不是严格比较(“===”)。

So if you want to remove duplicates inside an array of objects, beware that it will compare each object properties, not compare object identity (instance).

因此,如果您想删除对象数组中的重复项,请注意它会比较每个对象的属性,而不是比较对象身份(实例)。

回答by Felix Kling

Well, array_unique()compares the string value of the elements:

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

Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2i.e. when the string representation is the same, the first element will be used.

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

So make sure to implement the __toString()method in your class and that it outputs the same value for equal roles, e.g.

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

class Role {
    private $name;

    //.....

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

}

This would consider two roles as equal if they have the same name.

如果两个角色具有相同的名称,这将认为它们是平等的。

回答by salathe

This answer uses in_array()since the nature of comparing objectsin PHP 5 allows us to do so. Making use of this object comparison behaviour requires that the array onlycontain objects, but that appears to be the case here.

这个答案之所以使用,是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);

回答by yankee

Here is a way to remove duplicated objects in an array:

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

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

回答by Remon

You can also serialize first:

您也可以先序列化:

$unique = array_map( 'unserialize', array_unique( array_map( 'serialize', $array ) ) );

As of PHP 5.2.9 you can just use optional sort_flag SORT_REGULAR:

从 PHP 5.2.9 开始,您可以只使用 optional sort_flag SORT_REGULAR

$unique = array_unique( $array, SORT_REGULAR );

回答by Arvid Vermote

You can also use they array_filter function, if you want to filter objects based on a specific attribute:

如果要根据特定属性过滤对象,也可以使用它们的 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;
});

回答by Silver Light

From here: http://php.net/manual/en/function.array-unique.php#75307

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

This one would work with objects and arrays also.

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

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

回答by Kellen Mace

If you have an indexed array of objects, and you want to remove duplicates by comparing a specific property in each object, a function like the remove_duplicate_models()one below can be used.

如果您有一个对象的索引数组,并且希望通过比较每个对象中的特定属性来删除重复项,remove_duplicate_models()则可以使用如下所示的函数。

class Car {
    private $model;

    public function __construct( $model ) {
        $this->model = $model;
    }

    public function get_model() {
        return $this->model;
    }
}

$cars = [
    new Car('Mustang'),
    new Car('F-150'),
    new Car('Mustang'),
    new Car('Taurus'),
];

function remove_duplicate_models( $cars ) {
    $models = array_map( function( $car ) {
        return $car->get_model();
    }, $cars );

    $unique_models = array_unique( $models );

    return array_values( array_intersect_key( $cars, $unique_models ) );
}

print_r( remove_duplicate_models( $cars ) );

The result is:

结果是:

Array
(
    [0] => Car Object
        (
            [model:Car:private] => Mustang
        )

    [1] => Car Object
        (
            [model:Car:private] => F-150
        )

    [2] => Car Object
        (
            [model:Car:private] => Taurus
        )

)

回答by Artem Sivak

This is very simple solution:

这是非常简单的解决方案:

$ids = array();

foreach ($relate->posts as $key => $value) {
  if (!empty($ids[$value->ID])) { unset($relate->posts[$key]); }
  else{ $ids[$value->ID] = 1; }
}

回答by jricher

array_unique works by casting the elements to a string and doing a comparison. Unless your objects uniquely cast to strings, then they won't work with array_unique.

array_unique 的工作原理是将元素转换为字符串并进行比较。除非您的对象唯一地转换为字符串,否则它们将无法与 array_unique 一起使用。

Instead, implement a stateful comparison function for your objects and use array_filterto throw out things the function has already seen.

相反,为您的对象实现一个有状态的比较函数,并使用array_filter丢弃函数已经看到的东西。