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

)

当前回答

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

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

其他回答

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

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

我解释了为什么我们使用“serialize”和“unserialize”的步骤:

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

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

步骤2:使值唯一

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

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

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

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

再次感谢你所做的一切。

唯一一个多维数组的简单而合理的方法如下:

如果你有一个这样的数组:

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

我希望这能澄清一切。

我对这个问题进行了大量的思考,并确定了最佳解决方案应该遵循两个规则。

为了可伸缩性,在适当的地方修改数组;不复制到新数组 对于性能,每个比较应该只进行一次

考虑到这一点,并考虑到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);上面之后要重新编号键。

这个解决方案只在一个数组列需要唯一性时才有用,例如,如果我们需要数组索引#0中的唯一性。

解决方案1:

使用array_filter和一个匿名函数和一个静态变量:

<?php

$list = [
    ['abc', 'def'],
    ['ghi', 'jkl'],
    ['mno', 'pql'],
    ['abc', 'def'],
    ['ghi', 'jkl'],
    ['mno', 'pql']
];

$list = array_filter($list, function ($item) {
    static $values = [];
    if (!in_array($item[0], $values)) {
        $values[] = $item[0];
        return true;
    } else {
        return false;
    }
});

var_dump($list);

解决方案2:

由于我们想要唯一性的值是字符串类型,我们可以重新映射原始全局数组,使用这些值作为键,这将在我们重新映射时删除重复的值:

<?php

$list = [
    ['abc', 'def'],
    ['ghi', 'jkl'],
    ['mno', 'pql'],
    ['abc', 'def'],
    ['ghi', 'jkl'],
    ['mno', 'pql']
];

$unique = [];

foreach ($list as $item) {
    $unique[$item[0]] = $item;
}

// Remap again to integers
$unique = array_values($unique);

var_dump($unique);

正如人们所说,array_unique()非常慢,下面是我用于一个层次的多维数组的代码片段。

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

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

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

在php.net中引用array_unique()函数页面的第一个用户贡献的注释