array_module을 객체에 적용하시겠습니까?
오브젝트에 대해 array_unique와 같은 메서드가 있습니까?병합하는 '역할' 개체가 있는 어레이가 여러 개 있는데 중복된 개체를 삭제합니다. : )
array_unique
는 다음 명령을 사용하여 오브젝트 배열과 함께 동작합니다.
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));
인쇄:
Array (
[0] => MyClass Object
(
[prop] => test1
)
[2] => MyClass Object
(
[prop] => test2
)
)
자세한 것은, http://3v4l.org/VvonH#v529 를 참조해 주세요.
경고: 엄밀한 비교("===")가 아닌 "==" 비교를 사용합니다.
따라서 오브젝트 배열 내에서 중복을 제거하는 경우 오브젝트 ID(인스턴스)가 아닌 각 오브젝트 속성을 비교합니다.
는 요소의 문자열 값을 비교합니다.
주의: 두 가지 요소는 다음과 같은 경우에만 동일한 것으로 간주됩니다.
(string) $elem1 === (string) $elem2
즉, 문자열 표현이 동일한 경우 첫 번째 요소가 사용됩니다.
따라서 클래스에서 메서드를 구현하고 동일한 역할에 대해 동일한 값을 출력해야 합니다.
class Role {
private $name;
//.....
public function __toString() {
return $this->name;
}
}
이렇게 하면 두 역할이 동일한 이름을 가진 경우 동일한 것으로 간주됩니다.
이 답변에서는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);
어레이 내에서 중복된 개체를 삭제하는 방법은 다음과 같습니다.
<?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);
먼저 시리얼화할 수도 있습니다.
$unique = array_map( 'unserialize', array_unique( array_map( 'serialize', $array ) ) );
PHP 5.2.9에서는 옵션만 사용할 수 있습니다.sort_flag SORT_REGULAR
:
$unique = array_unique( $array, SORT_REGULAR );
특정 Atribut에 따라 개체를 필터링하는 경우 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;
});
연락처 : 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);
}
?>
오브젝트의 인덱스 배열을 가지고 있으며 각 오브젝트의 특정 속성을 비교하여 중복을 제거하려면 다음과 같은 기능을 사용합니다.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 ) );
결과는 다음과 같습니다.
Array
(
[0] => Car Object
(
[model:Car:private] => Mustang
)
[1] => Car Object
(
[model:Car:private] => F-150
)
[2] => Car Object
(
[model:Car:private] => Taurus
)
)
어레이에서 중복 인스턴스를 필터링(예: "===" 비교)해야 하는 경우 적절하고 빠른 방법으로 다음을 수행할 수 있습니다.
- 개체만 포함하는 배열이 무엇인지 확인했습니다.
- 키를 보존할 필요가 없습니다.
다음과 같습니다.
//sample data
$o1 = new stdClass;
$o2 = new stdClass;
$arr = [$o1,$o1,$o2];
//algorithm
$unique = [];
foreach($arr as $o){
$unique[spl_object_hash($o)]=$o;
}
$unique = array_values($unique);//optional - use if you want integer keys on output
이것은 매우 간단한 해결책입니다.
$ids = array();
foreach ($relate->posts as $key => $value) {
if (!empty($ids[$value->ID])) { unset($relate->posts[$key]); }
else{ $ids[$value->ID] = 1; }
}
또한 콜백 함수를 사용하여 어레이를 고유하게 만들 수도 있습니다(예를 들어 개체 또는 메서드의 속성을 비교하려는 경우).
이 목적으로 사용하는 일반적인 기능은 다음과 같습니다.
/**
* Remove duplicate elements from an array by comparison callback.
*
* @param array $array : An array to eliminate duplicates by callback
* @param callable $callback : Callback accepting an array element returning the value to compare.
* @param bool $preserveKeys : Add true if the keys should be perserved (note that if duplicates eliminated the first key is used).
* @return array: An array unique by the given callback
*/
function unique(array $array, callable $callback, bool $preserveKeys = false): array
{
$unique = array_intersect_key($array, array_unique(array_map($callback, $array)));
return ($preserveKeys) ? $unique : array_values($unique);
}
사용 예:
$myUniqueArray = unique($arrayToFilter,
static function (ExamQuestion $examQuestion) {
return $examQuestion->getId();
}
);
array_unique
버전( strict)===
) 비교, 키 유지:
function array_unique_strict(array $array): array {
$result = [];
foreach ($array as $key => $item) {
if (!in_array($item, $result, true)) {
$result[$key] = $item;
}
}
return $result;
}
사용방법:
class Foo {}
$foo1 = new Foo();
$foo2 = new Foo();
array_unique_strict( ['a' => $foo1, 'b' => $foo1, 'c' => $foo2] ); // ['a' => $foo1, 'c' => $foo2]
array_module은 요소를 문자열에 캐스팅하여 비교함으로써 동작합니다.오브젝트가 문자열에 고유하게 캐스팅되지 않는 한 array_unique와 함께 동작하지 않습니다.
대신 오브젝트에 스테이트풀 비교 기능을 구현하고 array_filter를 사용하여 함수가 이미 확인한 것을 폐기합니다.
이것은 객체를 단순한 속성과 비교하는 방법이며, 동시에 고유한 컬렉션을 받는 방법은 다음과 같습니다.
class Role {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
$roles = [
new Role('foo'),
new Role('bar'),
new Role('foo'),
new Role('bar'),
new Role('foo'),
new Role('bar'),
];
$roles = array_map(function (Role $role) {
return ['key' => $role->getName(), 'val' => $role];
}, $roles);
$roles = array_column($roles, 'val', 'key');
var_dump($roles);
유언 출력:
array (size=2)
'foo' =>
object(Role)[1165]
private 'name' => string 'foo' (length=3)
'bar' =>
object(Role)[1166]
private 'name' => string 'bar' (length=3)
개체 배열이 있고 이 컬렉션을 필터링하여 모든 중복을 제거하려면 array_filter를 익명 함수와 함께 사용할 수 있습니다.
$myArrayOfObjects = $myCustomService->getArrayOfObjects();
// This is temporary array
$tmp = [];
$arrayWithoutDuplicates = array_filter($myArrayOfObjects, function ($object) use (&$tmp) {
if (!in_array($object->getUniqueValue(), $tmp)) {
$tmp[] = $object->getUniqueValue();
return true;
}
return false;
});
중요:반드시 합격해야 한다는 것을 기억하라.$tmp
callback 함수를 필터링하지 않으면 동작하지 않습니다.
언급URL : https://stackoverflow.com/questions/2426557/array-unique-for-objects
'programing' 카테고리의 다른 글
실제 효과가 없는 트랜잭션은 온디스크 데이터베이스에 영향을 미칩니까? (0) | 2022.11.07 |
---|---|
결과를 기다리지 않는 php exec 명령(또는 이와 유사) (0) | 2022.11.07 |
1부터 시작하는 인덱스를 사용하여 PHP에서 어레이를 다시 인덱싱하려면 어떻게 해야 합니까? (0) | 2022.11.07 |
Python은 강한 타입입니까? (0) | 2022.11.06 |
Eclipse에서 테스트하는 동안 -D 시스템 속성을 통과하려면 어떻게 해야 합니까? (0) | 2022.11.06 |