如何在PHP中从多维数组中删除重复值
如何在PHP中从多维数组中删除重复值 示例阵列:如何在PHP中从多维数组中删除重复值,php,arrays,duplicate-data,Php,Arrays,Duplicate Data,如何在PHP中从多维数组中删除重复值 示例阵列: Array ( [0] => Array ( [0] => abc [1] => def ) [1] => Array ( [0] => ghi [1] => jkl ) [2] => Array ( [0] => mno [1] =&g
Array
(
[0] => Array
(
[0] => abc
[1] => def
)
[1] => Array
(
[0] => ghi
[1] => jkl
)
[2] => Array
(
[0] => mno
[1] => pql
)
[3] => Array
(
[0] => abc
[1] => def
)
[4] => Array
(
[0] => ghi
[1] => jkl
)
[5] => Array
(
[0] => mno
[1] => pql
)
)
用户对文档的评论对此有许多解决方案。以下是其中之一:
rbnsn.com上的kenrbnsn2005年9月27日12:09 另一个数组_是多维数组中唯一的。我只在二维数组上测试过这个,但它可能会被推广更多,或者使用递归 此函数使用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);
}
这是另一种方式。也将保留密钥
function array_unique_multidimensional($input)
{
$serialized = array_map('serialize', $input);
$unique = array_unique($serialized);
return array_intersect_key($input, $unique);
}
这是另一种方法。不保存中间变量 我们使用它来消除各种重叠查询的重复结果
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
易于阅读的解决方案,可能不是最有效的:
function arrayUnique($myArray){
if(!is_array($myArray))
return $myArray;
foreach ($myArray as &$myvalue){
$myvalue=serialize($myvalue);
}
$myArray=array_unique($myArray);
foreach ($myArray as &$myvalue){
$myvalue=unserialize($myvalue);
}
return $myArray;
}
我有一个类似的问题,但我找到了一个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'));
?>
从5.2.9开始,如果您使用常规排序
标志,则可以使用:
$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"
}
}
这使得函数比较元素是否相等,就好像使用了$a==$b
,这非常适合您的情况
输出
数组
(
[0]=>阵列
(
[0]=>abc
[1] =>def
)
[1] =>阵列
(
[0]=>ghi
[1] =>jkl
)
[2] =>阵列
(
[0]=>mno
[1] =>pql
)
)
但是,请记住,这表明:
array\u unique()
不适用于多维数组
序列化和唯一的替代方法
*/如果需要消除特定键(如mysqli id)上的重复项,这里有一个简单的函数
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
)
)
奖励积分
您可以传递一个键数组并添加一个外部foreach,但每个额外键的速度将慢2倍。如果您有这样的数组
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
)
)
foreach($array as $k=>$v){
$unique=array_unique($v);
$array[$k]=$unique;
}
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);
或
下面的代码可能会有所帮助
$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]);
}
}
}
}
}
$data1=array();
$data1=$data;
对于($q=0;$q我对这个问题进行了很多思考,并确定最佳解决方案应该遵循两条规则
为实现可扩展性,请就地修改阵列;无需复制到新阵列
对于性能,每次比较只能进行一次
考虑到这一点,并考虑到PHP的所有怪癖,下面是我提出的解决方案。与其他一些答案不同,它能够根据您想要的任何键删除元素。输入数组应该是数字键
$serialized_array = array_map("serialize", $input);
foreach ($serialized_array as $key => $val) {
$result[$val] = true;
}
$output = array_map("unserialize", (array_keys($result)));
$count\u array=count($input);
对于($i=0;$i<$count\u数组;$i++){
if(isset($input[$i])){
对于($j=$i+1;$j<$count\u数组;$j++){
if(isset($input[$j])){
//这是你做重复比较的地方
如果($input[$i]['checksum']==$input[$j]['checksum'])){
未设置($input[$j]);
}
}
}
}
}
唯一的缺点是迭代完成时键不按顺序排列。如果您随后只使用foreach循环,这不是问题,但是如果您需要使用for循环,您可以将$input=array\u values($input);
放在上面之后对键重新编号。正如人们所说的array\u unique()
非常慢,下面是一个用于一级多维数组的代码片段
Array=>
[0] => (array)
'user' => 'john'
'age' => '23'
[1] => (array)
'user' => 'jane'
'age' => '20'
[2]=> (array)
'user' => 'john'
'age' => '23'
如果您有这样一个数组,请参考array\u unique()
data = array
(
[0] => array
(
[subject] => d
[object] => b
),
[1] => array
(
[subject] => c
[object] => a
),
[2] => array
(
[subject] => c
[object] => d
)
)
foreach($array as $k=>$v){
$unique=array_unique($v);
$array[$k]=$unique;
}
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);
(users是数组的名称)
如果要删除重复项,请执行以下操作:
$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);
$serialized=array();
对于($i=0;$i
可以是一个解决方案:p如果“删除重复项”意味着“删除重复项,但让其中一个出现”,则解决方案可能是首先在“标识符列”上应用数组\u unique(…)
,然后在原始数组中删除已从列数组中删除的所有键:
Array
(
[0] => Array
(
[id] => 123
[foo] => aaa
[bar] => bbb
)
[2] => Array
(
[id] => 567
[foo] => eee
[bar] => fff
)
)
结果是:
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
很多人问我如何制作独特的多维数组。我从你的评论中得到了参考,这对我很有帮助
首先,感谢@jeromegamez@daveilers提供的解决方案。但每次我给出答案时,他们都会问我这个“序列化”和“非序列化”是如何工作的。这就是为什么我想与大家分享这个原因,以便帮助更多人理解背后的概念
我正在解释为什么我们要分步骤使用“序列化”和“非序列化”:
步骤1:将多维数组转换为一维数组
若要将多维数组转换为一维数组,请首先生成数组中所有元素(包括嵌套数组)的字节流表示形式。serialize()函数可以生成值的字节流表示形式。若要生成所有元素的字节流表示形式,请调用serialize()函数中的函数作为回调函数。无论多维数组有多少个级别,结果都将是一维数组
步骤2:使值唯一
要使此一维数组唯一,请使用array_unique()函数
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
)
)
步骤3:将其还原为多维数组
虽然数组现在是唯一的,但值看起来像字节流表示法。要将其还原为多维数组,请使用unserialize()函数
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
)
)
再次感谢您所做的一切。以下是一种非常简单且符合逻辑的方法来唯一化多维数组:
如果您有这样的数组:
data = array
(
[0] => array
(
[subject] => d
[object] => b
),
[1] => array
(
[subject] => c
[object] => a
),
[2] => array
(
[subject] => c
[object] => d
)
)
foreach($array as $k=>$v){
$unique=array_unique($v);
$array[$k]=$unique;
}
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);
使用foreach
解决此问题:
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;
}
如果你想重新安排ke的顺序