如何在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

如何在PHP中从多维数组中删除重复值

示例阵列:

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上的kenrbnsn
2005年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的顺序