PHP多维数组去重

21

不确定这个问题是否是需要删除的重复内容,但我在其他地方找不到答案,所以我试着问一下。

我有一个二维数组,看起来像这样:

Array
(
[0] => Array
    (
        [0] => dave
        [1] => jones
        [2] => c@b.c
    )

[1] => Array
    (
        [0] => john
        [1] => jones
        [2] => a@b.c

    )

[2] => Array
    (
        [0] => bruce
        [1] => finkle
        [2] => c@b.c
    )
)

我想要删除那些拥有重复电子邮件的条目。因此在上面的示例中,我只想删除[ ][ 0 ]或[ ][ 2 ]中的一个。我不关心检查名称或其他任何内容,我只需要基于单个值对子数组进行去重。

目前我有类似下面这样的东西:

  if(is_array($array) && count($array)>0){
  foreach ($array as $subarray) {
    $duplicateEmail[$subarray[2]] = isset($duplicateEmail[$subarray[2]]);
    unset($duplicateEmail[$subarray[2]]);
   }
  }

但这样做就不太对。非常感谢任何帮助。

6个回答

29

一种使用数组索引唯一性的快速解决方案:

$newArr = array();
foreach ($array as $val) {
    $newArr[$val[2]] = $val;    
}
$array = array_values($newArr);

注意1:从上面可以看出,对于电子邮件地址,最后匹配的结果被使用而不是第一个。这可以通过替换第二行来改变。

foreach (array_reverse($array) as $val) {

注意2:结果数组中的索引有些混乱。但我猜这没关系…


你的“for”应该改成“foreach”,但除此之外它运行良好,谢谢。 - Kevin Carmody
@Cassy - 我把这个变成了一个函数,用在我正在编写的小应用程序中,谢谢你! - Shackrock
谢谢,这个方法很管用。不知道为什么一开始没看到这个答案。现在问题解决了! :) - MR_AMDEV

15
更简单的解决方案。
$unique = array_map('unserialize', array_unique(array_map('serialize', $array)));

echo "<pre>";
print_r($unique);

1
那并没有回答问题。那只是检查唯一的数组而不是它们的属性。还是感谢你再试一次。 - Kevin Carmody

8
array_unique() 的用户评论中有一些解决方案。例如:
    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://uk.php.net/manual/en/function.array-unique.php#57202

这个函数用于从数组中移除重复的值,并返回一个新的数组。该函数可以接受一个可选参数,用于指定比较元素时所使用的算法。如果不指定该参数,则默认使用全等比较(即类型和值都相同)。注意,该函数会保留原始数组中的键名。

3
如果我没记错的话,它覆盖整个子数组而不是单个值。 - Kevin Carmody

3
$array = array(
    array('dave','jones','c@b.c'),
    array('dave','jones','a@c.d'),
    array('dave','jones','c@b.c'),
    array('dave','jones','e@v.d'),
    array('dave','jones','a@c.d')   
);

$copy = $array; // create copy to delete dups from
$usedEmails = array(); // used emails

for( $i=0; $i<count($array); $i++ ) {

    if ( in_array( $array[$i][2], $usedEmails ) ) {
        unset($copy[$i]);
    }
    else {
        $usedEmails[] = $array[$i][2];
    }

}

print_r($copy);

1

使用 SORT_REGULAR 作为第二个参数。

$uniqueArray = array_unique($array, SORT_REGULAR);

0

我的建议:

protected function arrayUnique($array, $preserveKeys = false)
{
    $uniqueArray = array();
    $hashes = array();

    foreach ($array as $key => $value) {
        if (true === is_array($value)) {
            $uniqueArray[$key] = $this->arrayUnique($value, $preserveKeys);

        } else {
            $hash = md5($value);

            if (false === isset($hashes[$hash])) {
                if ($preserveKeys) {
                    $uniqueArray[$key] = $value;
                } else {
                    $uniqueArray[] = $value;
                }

                $hashes[$hash] = $hash;
            }
        }
    }

    return $uniqueArray;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接