Answers:
这是另一种方式。没有中间变量被保存。
我们使用它来消除来自各种重叠查询的结果。
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
serialize(array('a' => '1', 'b' => '1'))
有所不同serialize(array('b' => '1', 'a' => '1'))
。对于用作sets
或的数组,此选项将失败(hash)maps
。
从5.2.9版本开始,您可以像下面这样array_unique()
使用SORT_REGULAR
标志:
array_unique($array, SORT_REGULAR);
这使得函数可以像$a == $b
使用元素一样比较元素是否相等,这非常适合您的情况。
输出量
Array
(
[0] => Array
(
[0] => abc
[1] => def
)
[1] => Array
(
[0] => ghi
[1] => jkl
)
[2] => Array
(
[0] => mno
[1] => pql
)
)
但是请记住,文档指出:
array_unique()
不适用于多维数组。
我有一个类似的问题,但是我找到了100%可行的解决方案。
<?php
function super_unique($array,$key)
{
$temp_array = [];
foreach ($array as &$v) {
if (!isset($temp_array[$v[$key]]))
$temp_array[$v[$key]] =& $v;
}
$array = array_values($temp_array);
return $array;
}
$arr="";
$arr[0]['id']=0;
$arr[0]['titel']="ABC";
$arr[1]['id']=1;
$arr[1]['titel']="DEF";
$arr[2]['id']=2;
$arr[2]['titel']="ABC";
$arr[3]['id']=3;
$arr[3]['titel']="XYZ";
echo "<pre>";
print_r($arr);
echo "unique*********************<br/>";
print_r(super_unique($arr,'titel'));
?>
用户对array_unique()文档的评论对此有很多解决方案。这是其中之一:
kenrbnsn at rbnsn dot com
2005年9月27日12:09另一个用于多维数组的Array_Unique。我仅在二维数组上对此进行了测试,但可能可以将其推广使用,或者使用递归。
此函数使用serialize,array_unique和unserialize函数来完成工作。
function multi_unique($array) { foreach ($array as $k=>$na) $new[$k] = serialize($na); $uniq = array_unique($new); foreach($uniq as $k=>$ser) $new1[$k] = unserialize($ser); return ($new1); }
这是从http://ca3.php.net/manual/en/function.array-unique.php#57202获得的。
如果“删除重复项”的意思是“删除重复项,但在那儿放一个”,一个解决方案可能是先array_unique(...)
在“标识符列”上应用,然后再在原始数组中删除所有已从列数组中删除的键。 :
$array = [
[
'id' => '123',
'foo' => 'aaa',
'bar' => 'bbb'
],
[
'id' => '123',
'foo' => 'ccc',
'bar' => 'ddd'
],
[
'id' => '567',
'foo' => 'eee',
'bar' => 'fff'
]
];
$ids = array_column($array, 'id');
$ids = array_unique($ids);
$array = array_filter($array, function ($key, $value) use ($ids) {
return in_array($value, array_keys($ids));
}, ARRAY_FILTER_USE_BOTH);
结果是:
Array
(
[0] => Array
(
[id] => 123
[foo] => aaa
[bar] => bbb
)
[2] => Array
(
[id] => 567
[foo] => eee
[bar] => fff
)
)
Array
(
[0] => Array
(
[id] => 1
[name] => john
)
[1] => Array
(
[id] => 2
[name] => smith
)
[2] => Array
(
[id] => 3
[name] => john
)
[3] => Array
(
[id] => 4
[name] => robert
)
)
$temp = array_unique(array_column($array, 'name'));
$unique_arr = array_intersect_key($array, $temp);
这将从数组中删除重复的名称。按键唯一
$array
的键从“ 0”开始。$array
如果$array
是先前数组操作的结果,则的键可能以另一个数字开头。用于array_values
将密钥重置为“ 0”
简单的解决方案:
array_unique($array, SORT_REGULAR)
只需将SORT_REGULAR选项用作第二个参数即可。
$uniqueArray = array_unique($array, SORT_REGULAR);
唯一化多维数组的一种非常简单且合乎逻辑的方法如下:
如果您有这样的数组:
Array
(
[Key1] => Array
(
[0] => Value1
[1] => Value2
[2] => Value1
[3] => Value3
[4] => Value1
)
[Key2] => Array
(
[0] => Value1
[1] => Value2
[2] => Value1
[3] => Value3
[4] => Value4
)
)
用于foreach
解决此问题:
foreach($array as $k=>$v){
$unique=array_unique($v);
$array[$k]=$unique;
}
它会给您以下结果:
Array
(
[Key1] => Array
(
[0] => Value1
[1] => Value2
[3] => Value3
)
[Key2] => Array
(
[0] => Value1
[1] => Value2
[3] => Value3
[4] => Value4
)
)
如果要重新排列键的顺序,
foreach($array as $k=>$v){
$unique= array_values(array_unique($v));
$array[$k]=$unique;
}
此操作将为您安排以下键值:
Array
(
[Key1] => Array
(
[0] => Value1
[1] => Value2
[2] => Value3
)
[Key2] => Array
(
[0] => Value1
[1] => Value2
[2] => Value3
[3] => Value4
)
)
我希望这会清除一切。
如果您有一个像这样的数组:
(用户是数组的名称)
Array=>
[0] => (array)
'user' => 'john'
'age' => '23'
[1] => (array)
'user' => 'jane'
'age' => '20'
[2]=> (array)
'user' => 'john'
'age' => '23'
并且您要删除重复项...然后:
$serialized = array();
for ($i=0; $i < sizeof($users); $i++) {
$test = in_array($users['user'], $serialized);
if ($test == false) {
$serialized[] = $users['user'];
}
}
可以解决的办法:P
正如人们所说的那样array_unique()
,这很慢,这是我用于一级多维数组的代码段。
$serialized_array = array_map("serialize", $input);
foreach ($serialized_array as $key => $val) {
$result[$val] = true;
}
$output = array_map("unserialize", (array_keys($result)));
$output = array_map('unserialize', array_keys($result));
很多人问我如何制作独特的多维数组。我已从您的评论中获取参考,这对我有帮助。
首先,感谢@jeromegamez @daveilers为您提供的解决方案。但是每次我给出答案时,他们都会问我这种“序列化”和“反序列化”是如何工作的。这就是为什么我想与您分享其原因,以帮助更多的人了解其背后的概念。
我正在解释为什么我们在步骤中使用“序列化”和“反序列化”:
步骤1:将多维数组转换为一维数组
要将多维数组转换为一维数组,请首先生成数组内部所有元素(包括嵌套数组)的字节流表示形式。serialize()函数可以生成值的字节流表示形式。要生成所有元素的字节流表示形式,请在array_map()函数内部调用serialize()函数作为回调函数。无论多维数组有多少层,结果都是一维数组。
步骤2:将值设为唯一
要使此一维数组唯一,请使用array_unique()函数。
步骤3:将其还原为多维数组
尽管该数组现在是唯一的,但这些值看起来像字节流表示形式。要将其还原为多维数组,请使用unserialize()函数。
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
再次感谢所有这些。
序列化和唯一的替代
$test = [
['abc','def'],
['ghi','jkl'],
['mno','pql'],
['abc','def'],
['ghi','jkl'],
['mno','pql'],
];
$result = array_reduce(
$test,
function($carry,$item){
if(!in_array($item,$carry)) {
array_push($carry,$item);
}
return $carry;
},
[]
);
var_dump($result);
/*
php unique.php
array(3) {
[0] =>
array(2) {
[0] =>
string(3) "abc"
[1] =>
string(3) "def"
}
[1] =>
array(2) {
[0] =>
string(3) "ghi"
[1] =>
string(3) "jkl"
}
[2] =>
array(2) {
[0] =>
string(3) "mno"
[1] =>
string(3) "pql"
}
}
* /
如果你有这样的数组
data = array
(
[0] => array
(
[subject] => a
[object] => c
),
[1] => array
(
[subject] => b
[object] => d
),
[2] => array
(
[subject] => d
[object] => b
),
[3] => array
(
[subject] => d
[object] => c
),
[4] => array
(
[subject] => c
[object] => a
),
[5] => array
(
[subject] => c
[object] => d
)
)
并且您想要获得这样的数组:
data = array
(
[0] => array
(
[subject] => a
[object] => c
),
[1] => array
(
[subject] => b
[object] => d
),
[2] => array
(
[subject] => d
[object] => c
)
)
要么
data = array
(
[0] => array
(
[subject] => d
[object] => b
),
[1] => array
(
[subject] => c
[object] => a
),
[2] => array
(
[subject] => c
[object] => d
)
)
以下代码可以帮助您
$data1 = array();
$data1 = $data;
for($q=0;$q<count($data);$q++)
{
for($p=0;$p<count($data1);$p++)
{
if (($data[$q]["subject"] == $data1[$p]["object"]) && ($data[$q]["object"] == $data1[$p]["subject"]))
{
$data1[$p]["subject"] = $data[$q]["subject"];
$data1[$p]["object"] = $data[$q]["object"];
}
}
}
$data1 = array_values(array_map("unserialize", array_unique(array_map("serialize", $data1))));
$data = $data1;
我考虑了很多这个问题,并确定最佳解决方案应遵循两个规则。
考虑到这一点,考虑到所有PHP的怪癖,下面是我想出的解决方案。与其他答案不同,它具有根据所需键删除元素的功能。输入数组应为数字键。
$count_array = count($input);
for ($i = 0; $i < $count_array; $i++) {
if (isset($input[$i])) {
for ($j = $i+1; $j < $count_array; $j++) {
if (isset($input[$j])) {
//this is where you do your comparison for dupes
if ($input[$i]['checksum'] == $input[$j]['checksum']) {
unset($input[$j]);
}
}
}
}
}
唯一的缺点是,当迭代完成时,键的顺序不正确。如果您随后仅使用foreach循环,那么这不是问题,但是如果您需要使用for循环,则可以$input = array_values($input);
在上述后面加上重新编号键。