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

时间:2008-11-21 02:50:31

标签: php arrays duplicate-data

如何从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
    )

)

20 个答案:

答案 0 :(得分:594)

这是另一种方式。不保存任何中间变量。

我们使用它来删除各种重叠查询的结果。

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));

答案 1 :(得分:206)

从5.2.9开始,如果您使用SORT_REGULAR标志,则可以使用array_unique()

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
        )

)

但请记住,the documentation表示:

  

array_unique()不适用于多维数组。

答案 2 :(得分:56)

我遇到了类似的问题,但我找到了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'));

?>

答案 3 :(得分:27)

另一种方式。也将保留密钥。

function array_unique_multidimensional($input)
{
    $serialized = array_map('serialize', $input);
    $unique = array_unique($serialized);
    return array_intersect_key($input, $unique);
}

答案 4 :(得分:19)

用户对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

答案 5 :(得分:12)

如果“删除重复项”意味着“删除重复项,但让其中一个”,则解决方案可能是首先在“标识符列”上应用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
        )

)

答案 6 :(得分:7)

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);

这将从数组中删除重复的名称。按键唯一

答案 7 :(得分:3)

只需使用SORT_REGULAR选项作为第二个参数。

$uniqueArray = array_unique($array, SORT_REGULAR);

答案 8 :(得分:3)

如果您需要消除特定键上的重复项,例如mysqli id,这里是一个简单的函数

function search_array_compact($data,$key){
    $compact = [];
    foreach($data as $row){
        if(!in_array($row[$key],$compact)){
            $compact[] = $row;
        }
    }
    return $compact;
}

奖励积分 您可以传递一组键并添加一个外部foreach,但每个附加键的速度会慢2倍。

答案 9 :(得分:2)

如果您有这样的数组:

(用户是数组的名称)

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

答案 10 :(得分:1)

很多人问我如何制作独特的多维数组。我已经参考了你的评论,这对我很有帮助。

首先,感谢@jeromegamez @daveilers提供的解决方案。但每次我给出答案时,他们都会问我这个'序列化'和'反序列化'是如何工作的。这就是为什么我想与你分享这个原因,以便它可以帮助更多的人理解这背后的概念。

我在解释为​​什么我们在步骤中使用'serialize'和'unserialize':

步骤1:将多维数组转换为一维数组

要将多维数组转换为一维数组,首先要生成数组内所有元素(包括嵌套数组)的字节流表示。 serialize()函数可以生成一个值的字节流表示。要生成所有元素的字节流表示,请将array_map()函数内的serialize()函数作为回调函数调用。无论多维数组有多少级别,结果都将是一维数组。

第2步:使值唯一

要使这个一维数组唯一,请使用array_unique()函数。

第3步:将其还原为多维数组

虽然数组现在是唯一的,但值看起来像字节流表示。要将其还原回多维数组,请使用unserialize()函数。

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));

再次感谢所有这一切。

答案 11 :(得分:1)

唯一一个多维数组的一种非常简单和合理的方法如下,

如果您有这样的数组:

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
        )
)

我希望这能清除一切。

答案 12 :(得分:1)

易于阅读的解决方案,可能效率不高:

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;

} 

答案 13 :(得分:1)

简单的解决方案:

array_unique($array, SORT_REGULAR)

答案 14 :(得分:0)

如果您有这样的数组

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;

答案 15 :(得分:0)

我已经考虑过这个问题并且已经确定最佳解决方案应该遵循两个规则。

  1. 为了扩展,请修改数组;没有复制到新阵列
  2. 为了表现,每次比较只应进行一次
  3. 考虑到这一点并考虑到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);之后重新编号键。

答案 16 :(得分:0)

正如人们所说array_unique()非常慢,这是我用于一级多维数组的片段。

$serialized_array = array_map("serialize", $input);

foreach ($serialized_array as $key => $val) {
     $result[$val] = true;
}

$output = array_map("unserialize", (array_keys($result)));

引用第一位用户提供的array_unique() function page in php.net

注释

答案 17 :(得分:0)

序列化和唯一

的替代方法

$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"
        }
}

* /

答案 18 :(得分:0)

根据标记为正确的答案,添加我的答案。添加了小代码只是为了重置索引-

$input = array_values(array_map("unserialize", array_unique(array_map("serialize", $inputArray))));

答案 19 :(得分:0)

我已经尝试过删除重复项。

$array = array_map("unserialize", array_unique(array_map("serialize", $array)));