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

243

我该如何在PHP中从数组中移除重复的值?


1
这取决于上下文。您有一个平面数组还是多维数组?您的所有值都是标量吗?您的值可能包含浮点/双精度值吗?您想保留第一次或最后一次出现的重复项吗?您需要重新索引数组吗?(nimey sara thomas似乎认为这是一个相关的步骤,出于某种奇怪的原因)您的样本输入在哪里?您确切的期望结果是什么?[mcve]s提出了最好的问题。这个问题需要澄清,以避免收到不合适甚至错误的答案。 - mickmackusa
1
数组中是什么类型的数据?它是直接数据还是更多的数组?如果是直接数据,那么是什么类型的数据?答案在很大程度上取决于这些信息。 - TylerH
27个回答

381

对于一维数组,请使用array_unique()。来自PHP手册:

接受一个输入数组并返回一个没有重复值的新数组。

请注意,键被保留。如果多个元素在给定标志下相等,则第一个相等元素的键和值将被保留。

请注意,array_unique()不适用于多维数组。

示例:

$array = array(1, 2, 2, 3);
$array = array_unique($array); // Array is now (1, 2, 3)

如果您想重新索引值,此外,您应该应用array_values


31
请注意,array_unique() 不适用于多维数组。 - Peter Ajtai
25
以上代码将保留数组元素的键。如果您想重新索引它们,还需要使用 array_values 函数:http://www.php.net/manual/zh/function.array-values.php - CodeVirtuoso
8
这段代码无效,请使用:$array = array_unique($array, SORT_REGULAR);该代码的作用是从数组中移除重复的元素,并保持原有的键值对关系。 - iniravpatel
1
@PeterAjtai:感谢您在评论区中的指出,这为我节省了很多时间。 - Nana Partykar

84

使用 array_values(array_unique($array));

array_unique: 用于去重数组 array_values: 用于重新索引


8
array_unique 返回一个键值对的对象,array_values 则仅返回值组成的数组。 - narainsagar
@narainsagar(以及8个评论点赞者)...什么?!?array_unique()要求第一个参数必须是数组。而array_values()也要求其参数必须是数组。如果你正在处理一个对象,那么这段代码将会出错。请不要误导研究人员,说些不实之词。 - mickmackusa

34
//Find duplicates 

$arr = array( 
    'unique', 
    'duplicate', 
    'distinct', 
    'justone', 
    'three3', 
    'duplicate', 
    'three3', 
    'three3', 
    'onlyone' 
);

$unique = array_unique($arr); 
$dupes = array_diff_key( $arr, $unique ); 
    // array( 5=>'duplicate', 6=>'three3' 7=>'three3' )

// count duplicates

array_count_values($dupes); // array( 'duplicate'=>1, 'three3'=>2 )

21
$result = array();
foreach ($array as $key => $value){
  if(!in_array($value, $result))
    $result[$key]=$value;
}

18

对我有效的唯一方法是:

$array = array_unique($array, SORT_REGULAR);

编辑: SORT_REGULAR 保持原始数组的顺序。


5
有时候使用array_unique()并不太合适,如果你想要获取独特的且重复的元素...
$unique=array("","A1","","A2","","A1","");
$duplicated=array();

foreach($unique as $k=>$v) {

if( ($kt=array_search($v,$unique))!==false and $k!=$kt )
 { unset($unique[$kt]);  $duplicated[]=$v; }

}

sort($unique); // optional
sort($duplicated); // optional

结果展示

array ( 0 => '', 1 => 'A1', 2 => 'A2', ) /* $unique */

array ( 0 => '', 1 => '', 2 => '', 3 => 'A1', ) /* $duplicated */

这个答案在循环过程中使用了 N 次搜索,效率不高。此答案进行了宽松的比较,这意味着它可能不适合一般/公共使用。 证明 - mickmackusa

4

我们可以轻松使用array_unique($array);来删除数组中的重复元素。

但这种方法的问题是,元素的索引顺序不一定会保持不变,如果稍后在其他位置使用该数组可能会出现问题。

用法

$arr = array_unique($arr);
$arr = array_values($arr);
print_r($arr);

或者

$arr = array_flip($arr);
$arr = array_flip($arr);
$arr = array_values($arr);
print_r($arr);

第一次翻转,将键值对反转,因此组合具有相似键(最初是值)的元素。

第二次翻转以恢复所有键值对。最后array_value()将每个值与从0开始的键设置。

注意:不适用于具有预定义键值对的关联数组


调用 array_flip() 不适合一般使用,因为即使不相同的值会被合并/丢失,如果它们共同对应于相同的字符串或整数值。此外,自 PHP4.3(也许更早,我不知道)以来,当值不是字符串或整数时,这种解决方案将发出警告。证明在本页上提供了十年前使用 array_unique() 的建议。我不推荐这个答案——它要么给出冗余的建议,要么给出不稳定的建议。 - mickmackusa

4
$a = array(1, 2, 3, 4); 
$b = array(1, 6, 5, 2, 9); 
$c = array_merge($a, $b);
$unique = array_keys(array_flip($c));
print_r($unique);

1
最快的方法是使用 PHP 内置的 array_flip 函数[1]。array_flip 将交换数组值和它们的键,由于一个数组不能有重复的键,你最终会得到一组唯一的键,这些键对应原始数组的值。要将这些键作为值检索出来,可以使用 array_keys 函数来检索你的唯一值。array_flip 和 array_keys 都是最坏情况下 O(n) 的函数,而 array_unique 的最坏情况是 O(n log(n))[2]。 - pawan kumar
2
请在您的答案中添加更多解释(不要放在评论区!)。给定的代码如何从单个数组中删除重复值?为什么需要两个数组? - Nico Haase
1
欢迎来到StackOverflow!我看到您在答案的评论中添加了一些解释,如果您将这些信息作为答案的一部分添加,那将会很有帮助。 - n4m31ess_c0d3r
2
似乎更合理的做法是将该评论作为对已经存在的答案(https://dev59.com/PHVC5IYBdhLWcg3wZwNT#52591730)进行编辑。 - ankhzet
您可以使用具有重复元素的单个数组。我曾经遇到过从两个数组中获取值并将其合并为一个数组,然后去除重复项的问题。 - pawan kumar
调用 array_flip() 不稳定/可靠,不适用于一般用途。尽管值不相同,但会合并/丢失共同转换为相同字符串或整数值的值。此外,自 PHP4.3(可能更早,我不知道)以来,当值不是字符串或整数时,此解决方案将发出警告。证明 我不支持这个答案,因为它不包含任何解释性文本,并且在某些情况下使用不安全。 - mickmackusa

3
我们可以创建这种类型的数组,以便将最后一个值更新到列或键值中,从而从数组中获取唯一的值...
$array = array (1,3,4,2,1,7,4,9,7,5,9);
    $data=array();
    foreach($array as $value ){

        $data[$value]= $value;

    }

    array_keys($data);
    OR
    array_values($data);

当值被用作键时,如果PHP在使用它们作为键时对其进行了变异,则使用值作为键不稳定。此答案可能不适合公共/一般使用。 - mickmackusa

2

根据数组的大小,我发现

$array = array_values( array_flip( array_flip( $array ) ) );

可以比array_unique更快。


这里发生的情况还有更多信息吗?使用更大或更小的数组会更快吗? - Fi Horan
双重翻转将删除重复的值,因为一个键不能存在两次,否则它会被覆盖。如果任何值是重复的,并且数组被翻转,最后一次出现(我假设)将成为键的值。 - Goldentoa11
在PHP 7中,我注意到多维数组翻转超过一次可能会意外地重新排序数组元素。 - vhs
调用 array_flip() 不适合一般使用,因为值会被合并/丢失,即使它们不完全相同但会共同转化为相同的字符串或整数值。此外,自 PHP4.3(也许更早,我不确定)以来,当值不是字符串或整数时,这种解决方案会发出警告。证明 - mickmackusa

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