3 回答
TA贡献1824条经验 获得超8个赞
array_unique
对于您手头的问题,我真的怀疑这是从使用标志时从数组中删除元素的方式来的 SORT_REGULAR
,方法是:
整理它
如果相邻项相等,则删除它们
Proxy
而且因为您的收藏中间确实有一个对象User
,这可能会导致您遇到当前面临的问题。
这似乎得到了sort
PHP 文档页面警告的支持。
警告对具有混合类型值的数组进行排序时要小心,因为如果是
sort()
,可能会产生意想不到的结果。sort_flags
SORT_REGULAR
现在对于一个可能的解决方案,这可能会给你带来更多 Symfony 风味的东西。
它使用ArrayCollection
filter
andcontains
方法来过滤第二个集合,只添加第一个集合中不存在的元素。
为了完全完整,该解决方案还利用use
语言结构将第二个传递ArrayCollection
给所需的闭包函数filter
。
这将导致一个新的ArrayCollection
不包含重复的用户。
public static function merge(Collection $a, Collection $b, bool $unique = false): Collection {
if($unique){
return new ArrayCollection(
array_merge(
$a->toArray(),
$b->filter(function($item) use ($a){
return !$a->contains($item);
})->toArray()
)
);
}
return new ArrayCollection(array_merge($a->toArray(), $b->toArray()));
}
TA贡献1808条经验 获得超4个赞
我知道你说你不想转换为字符串,但我看到你还没有出路,所以我建议你对serialize数组中的每个对象使用该函数,我没有找到方法比较未转换为数组或字符串的对象(如果您不熟悉字符串或数组,则不能尝试转换为二进制或十六进制,但我不知道是否可以转换为二进制或十六进制而不转换为字符串).
但是,如果你使用serialize,你可以在 php 的读取数据中序列化对象,与其他序列化对象相比,这个方法 ( serialize) 是安全的,因为你可以做一个unserialize, 并再次获得原始对象。
所以你可以序列化数组中的所有元素,然后,你可以array_unique像这样使用:
<?php
header("Content-Type: application/json");
class MyClass
{
public $var1;
public $var2;
function __construct($var1, $var2)
{
$this->var1 = $var1;
$this->var2 = $var2;
}
}
$arr = [
"a",
"a",
[1,2,3],
"b",
[1,2,3],
new MyClass(1,1),
new MyClass(1,new MyClass(1,1)),
new MyClass(1,new MyClass(1,1)),
];
$arrSerilized = array_map("serialize", $arr);
var_dump(
array_map(
"unserialize",
array_unique(
$arrSerilized,
SORT_STRING
)
)
);
/* output:
array(5) {
[0]=>
string(1) "a"
[2]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
[3]=>
string(1) "b"
[5]=>
object(MyClass)#6 (2) {
["var1"]=>
int(1)
["var2"]=>
int(1)
}
[6]=>
object(MyClass)#7 (2) {
["var1"]=>
int(1)
["var2"]=>
object(MyClass)#8 (2) {
["var1"]=>
int(1)
["var2"]=>
int(1)
}
}
}
*/
希望这对你有帮助,祝你有美好的一天!
PS:你serialize可以在不同的变量类型中保存相同的值,比如1在"1"不同的php读取数据中序列化
TA贡献1830条经验 获得超3个赞
在不了解您的实体类的情况下,很难猜测为什么会这样。但我想你的主要问题是__toString()method 。如果您尚未定义它,则应添加一个,以便它为每个实体对象返回一个唯一/不同的字符串。如果它已经定义,请确保它返回不同的字符串。
class User{
private $name;
function __construct($name){
$this->name=$name;
}
function __toString(){
return $this->name;
}
}
$user = [];
$users[] = new User("User1");
$users[] = new User("User2");
$users[] = new User("User3");
$user1= $users[0];
$users[]=$user1; //duplicate
echo(count(array_unique($users))); // output should be 3
鉴于有关实体类的信息有限,我可以猜到这里。
编辑:
阅读您的编辑后,我猜您将自己锁定在其中。Sincearray_unique将根据您传递的 sort_flag 尝试将实体对象转换为字符串或数字。更多关于array_unique。因此,您需要实现 __toString() 或添加一些公共属性来定义对象对实体的唯一性,例如
class User{
public $id;
private $name;
function __construct($id,$name){
$this->id=$id;
$this->name=$name;
}
}
$user = [];
$users[] = new User(1,"User1");
$users[] = new User(2,"User2");
$users[] = new User(3,"User3");
$user1= $users[0];
$users[]=$user1; //duplicate
echo(count(array_unique($users, SORT_REGULAR))); // output should be 3
请注意公共财产$id和SORT_REGULAR旗帜。
- 3 回答
- 0 关注
- 142 浏览
添加回答
举报