(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)
array_unique —Removes duplicate values from an array
Takes an inputarray and returns a new array without duplicate values.
Note that keys are preserved. If multiple elements compare equal under the givenflags, then the key and value of the first equal element will be retained.
Note: Two elements are considered equal if and only if
(string) $elem1 === (string) $elem2, i.e. when the string representation is the same, the first element will be used.
arrayThe input array.
flags The optional second parameterflags may be used to modify the comparison behavior using these values:
Comparison type flags:
SORT_REGULAR - compare items normally (don't change types)SORT_NUMERIC - compare items numericallySORT_STRING - compare items as stringsSORT_LOCALE_STRING - compare items as strings, based on the current locale.Returns the filtered array.
| Version | Description |
|---|---|
| 7.2.0 | Ifflags isSORT_STRING, formerlyarray has been copied and non-unique elements have been removed (without packing the array afterwards), but now a new array is built by adding the unique elements. This can result in different numeric indexes. |
Example #1array_unique() example
<?php
$input= ["a"=>"green","red","b"=>"green","blue","red"];
$result=array_unique($input);
print_r($result);
?>The above example will output:
Array( [a] => green [0] => red [1] => blue)
Example #2array_unique() and types
<?php
$input= [4,"4","3",4,3,"3"];
$result=array_unique($input);
var_dump($result);
?>The above example will output:
array(2) { [0] => int(4) [2] => string(1) "3"}Note: Note thatarray_unique() is not intended to work on multi dimensional arrays.
Create multidimensional array unique for any single key index.e.g I want to create multi dimentional unique array for specific codeCode : My array is like this,<?php$details= array(0=> array("id"=>"1","name"=>"Mike","num"=>"9876543210"),1=> array("id"=>"2","name"=>"Carissa","num"=>"08548596258"),2=> array("id"=>"1","name"=>"Mathew","num"=>"784581254"),);?>You can make it unique for any field like id, name or num.I have develop this function for same :<?phpfunctionunique_multidim_array($array,$key) {$temp_array= array();$i=0;$key_array= array(); foreach($arrayas$val) { if (!in_array($val[$key],$key_array)) {$key_array[$i] =$val[$key];$temp_array[$i] =$val; }$i++; } return$temp_array;}?>Now, call this function anywhere from your code,something like this,<?php$details=unique_multidim_array($details,'id');?>Output will be like this :<?php$details= array(0=> array("id"=>"1","name"=>"Mike","num"=>"9876543210"),1=> array("id"=>"2","name"=>"Carissa","num"=>"08548596258"),);?>Because of PHP comparaisons modalities, you can never distinguish null from others falsy values.Note the absorbing nature of true and false booleans in mix types array.<?php$a= [true,false,null,'','0','123',0,123];foreach (['SORT_REGULAR','SORT_NUMERIC','SORT_STRING','SORT_LOCALE_STRING'] as$flag) {$a_new=array_unique($a,constant($flag)); echo"{$flag} ==> ";var_dump($a_new);}/*Gives :SORT_REGULAR ==> array(2) { [0]=> bool(true) [1]=> bool(false)}SORT_NUMERIC ==> array(3) { [0]=> bool(true) [1]=> bool(false) [5]=> string(3) "123"}SORT_STRING ==> array(4) { [0]=> bool(true) [1]=> bool(false) [4]=> string(1) "0" [5]=> string(3) "123"}SORT_LOCALE_STRING ==> array(4) { [0]=> bool(true) [1]=> bool(false) [4]=> string(1) "0" [5]=> string(3) "123"}*/modified code originally posted by Ghanshyam Katriya(anshkatriya at gmail) [highest voted comment here].1. In php 7.4 counter $i breaks the function. Removed completely (imo was waste of keystrokes anyway).2. I added second return value - array of duplicates. So you can take both and compare them (I had to).Example array (copy-paste from original post):<?php$details= array(0=> array("id"=>"1","name"=>"Mike","num"=>"9876543210"),1=> array("id"=>"2","name"=>"Carissa","num"=>"08548596258"),2=> array("id"=>"1","name"=>"Mathew","num"=>"784581254"),);?> Function:<?phpfunctionunique_multidim_array($array,$key) : array {$uniq_array= array();$dup_array= array();$key_array= array(); foreach($arrayas$val) { if (!in_array($val[$key],$key_array)) {$key_array[] =$val[$key];$uniq_array[] =$val;/* # 1st list to check: # echo "ID or sth: " . $val['building_id'] . "; Something else: " . $val['nodes_name'] . (...) "\n";*/} else {$dup_array[] =$val;/* # 2nd list to check: # echo "ID or sth: " . $val['building_id'] . "; Something else: " . $val['nodes_name'] . (...) "\n";*/} } return array($uniq_array,$dup_array,/* $key_array */);}?> Usage:<?phplist($unique_addresses,$duplicates,/* $unique_keys */) =unique_multidim_array($details,'id');?>Then:var_dump($unique_addresses);orvar_dump($duplicates);or foreach or whatever. Personally I just echo-ed 1st and then 2nd (both DOUBLE COMMENTED) list in function itself (then copied both to notepad++ and compared them - just to be 100% sure), but in case you want to do something else with it - enjoy :)Plus - as a bonus - you also get an array of UNIQUE keys you searched for (just uncomment >$key_array< in both: function return and function call code).From example array code returns:var_dump($unique_addresses); array(2) { [0]=> array(3) { ["id"]=> string(1) "1" ["name"]=> string(4) "Mike" ["num"]=> string(10) "9876543210" } [1]=> array(3) { ["id"]=> string(1) "2" ["name"]=> string(7) "Carissa" ["num"]=> string(11) "08548596258" }}var_dump($duplicates); array(1) { [0]=> array(3) { ["id"]=> string(1) "1" ["name"]=> string(6) "Mathew" ["num"]=> string(9) "784581254" }}Plus keys, if you want.P.S.: in my - practical - case of DB querying I got around 4k uniques and 15k dupes :)I find it odd that there is no version of this function which allows you to use a comparator callable in order to determine items equality (like array_udiff and array_uintersect). So, here's my version for you:<?phpfunctionarray_uunique(array$array, callable$comparator): array {$unique_array= []; do {$element=array_shift($array);$unique_array[] =$element;$array=array_udiff($array, [$element],$comparator); } while (count($array) >0); return$unique_array;}?>And here is a test code:<?phpclassFoo{ public$a; public function__construct(int $a) {$this->a=$a; }}$array_of_objects= [newFoo(2), newFoo(1), newFoo(3), newFoo(2), newFoo(2), newFoo(1)];$comparator= function (Foo $foo1,Foo $foo2):int{ return$foo1->a<=>$foo2->a;};var_dump(array_uunique($array_of_objects,$comparator));// should output [Foo(2), Foo(1), Foo(3)]?>It's often faster to use a foreache and array_keys than array_unique:<?php $max=1000000;$arr=range(1,$max,3);$arr2=range(1,$max,2);$arr=array_merge($arr,$arr2);$time= -microtime(true);$res1=array_unique($arr);$time+=microtime(true); echo"deduped to ".count($res1)." in ".$time;// deduped to 666667 in 32.300781965256$time= -microtime(true);$res2= array(); foreach($arras$key=>$val) {$res2[$val] =true; }$res2=array_keys($res2);$time+=microtime(true); echo"<br />deduped to ".count($res2)." in ".$time;// deduped to 666667 in 0.84372591972351?>In reply to performance tests array_unique vs foreach.In PHP7 there were significant changes to Packed and Immutable arrays resulting in the performance difference to drop considerably. Here is the same test on php7.1 here;http://sandbox.onlinephpfunctions.com/code/2a9e986690ef8505490489581c1c0e70f20d26d1$max = 770000; //large enough number within memory allocation$arr = range(1,$max,3); $arr2 = range(1,$max,2); $arr = array_merge($arr,$arr2); $time = -microtime(true); $res1 = array_unique($arr); $time += microtime(true); echo "deduped to ".count($res1)." in ".$time; // deduped to 513333 in 1.0876770019531$time = -microtime(true); $res2 = array(); foreach($arr as $key=>$val) { $res2[$val] = true; } $res2 = array_keys($res2); $time += microtime(true); echo "<br />deduped to ".count($res2)." in ".$time; // deduped to 513333 in 0.054931879043579<?php//removes duplicated objetcs from an array according to the property givenclassArrayFilter{ public static functiondedupe_array_of_objets(array$array,string $property) : array {$i=0;$filteredArray= array();$keyArray= array(); foreach($arrayas$item) { if (!in_array($item->$property,$keyArray)) {$keyArray[$i] =$item->$property;$filteredArray[$i] =$item; }$i++; } return$filteredArray; }}Following the Ghanshyam Katriya idea, but with an array of objects, where the $key is related to object propriety that you want to filter the uniqueness of array:<?phpfunctionobj_multi_unique($obj,$key=false) {$totalObjs=count($obj); if (is_array($obj) &&$totalObjs>0&&is_object($obj[0]) && ($key&& !is_numeric($key))) { for ($i=0;$i<$totalObjs;$i++) { if (isset($obj[$i])) { for ($j=$i+1;$j<$totalObjs;$j++) { if (isset($obj[$j]) &&$obj[$i]->{$key} ===$obj[$j]->{$key}) { unset($obj[$j]); } } } } returnarray_values($obj); } else { throw newException('Invalid argument or your array of objects is empty'); } }?>I needed to identify email addresses in a data table that were replicated, so I wrote the array_not_unique() function:<?phpfunctionarray_not_unique($raw_array) {$dupes= array();natcasesort($raw_array);reset($raw_array);$old_key=NULL;$old_value=NULL; foreach ($raw_arrayas$key=>$value) { if ($value===NULL) { continue; } if ($old_value==$value) {$dupes[$old_key] =$old_value;$dupes[$key] =$value; }$old_value=$value;$old_key=$key; }return$dupes;}$raw_array= array();$raw_array[1] ='abc@xyz.com';$raw_array[2] ='def@xyz.com';$raw_array[3] ='ghi@xyz.com';$raw_array[4] ='abc@xyz.com';// Duplicate$common_stuff=array_not_unique($raw_array);var_dump($common_stuff);?>$a = new StdClass();$b = new StdClass();var_dump(array_unique([$a, $b, $b, $a], SORT_REGULAR));//array(1) {// [0]=>// object(stdClass)#1 (0) {// }//}$a->name = 'One';$b->name = 'Two';var_dump(array_unique([$a, $b, $b, $a], SORT_REGULAR));//array(2) {// [0]=>// object(stdClass)#1 (1) {// ["name"]=>// string(3) "One"// }// [1]=>// object(stdClass)#2 (1) {// ["name"]=>// string(3) "Two"// }//}Here is a solution to make unique values keeping empty values for an array with keys :<?phpfunctionarray_unique_kempty($array) {$values=array_unique($array);$return=array_combine(array_keys($array),array_fill(0,count($array),null)); returnarray_merge($return,$values);}$myArray= ["test1"=>"aaa","test2"=>null,"test3"=>"aaa","test4"=>"bbb","test5"=>null,"test6"=>"ccc","test7"=>"ddd","test8"=>"ccc"];echo"<pre>".print_r(array_unique_kempty($myArray),true)."</pre>";/*Array( [test1] => aaa [test2] => [test3] => [test4] => bbb [test5] => [test6] => ccc [test7] => ddd [test8] => )*/?>Case insensitive; will keep first encountered value.<?phpfunctionarray_iunique($array) {$lowered=array_map('strtolower',$array); returnarray_intersect_key($array,array_unique($lowered));}?>Case insensitive for PHP v4.x and up.<?phpfunctionin_iarray($str,$a) { foreach ($aas$v) { if (strcasecmp($str,$v) ==0) { returntrue; } } returnfalse;}functionarray_iunique($a) {$n= array(); foreach ($aas$k=>$v) { if (!in_iarray($v,$n)) {$n[$k]=$v; } } return$n;}$input= array("aAa","bBb","cCc","AaA","ccC","ccc","CCC","bBB","AAA","XXX");$result=array_iunique($input);print_r($result);/*Array( [0] => aAa [1] => bBb [2] => cCc [9] => XXX)*/?>My object unique function:<?phpfunctionobject_unique($obj){$objArray= (array)$obj;$objArray=array_intersect_assoc(array_unique($objArray),$objArray); foreach($objas$n=>$f) { if( !array_key_exists($n,$objArray) ) unset($obj->$n); } return$obj;}?>And these code:<?phpclassTest{ public$pr0='string'; public$pr1='string1'; public$pr2='string'; public$pr3='string2';}$obj= newTest;var_dump(object_unique($obj) );?>returns:object(Test)[1] public 'pr0' => string 'string' (length=6) public 'pr1' => string 'string1' (length=7) public 'pr3' => string 'string2' (length=7)array_unique is not compatible with php 8.1 enums because enums don't have a string representation yet (even the BackedEnum of string type…).You get an error: "Object of class XXXX could not be converted to string."So I wrote this function that creates a string representation of the enums and use the array keys to remove duplicates:<?phpfunctionarray_unique_81(array$values): array{$unique= []; foreach ($valuesas$value) { if ($valueinstanceof\UnitEnum) {$key='e:'.\get_class($value) .':'.$value->name; } else {$key='s:'. (string)$value; }$unique[$key] =$value; } return\array_values($unique);}?>If you find the need to get a sorted array without it preserving the keys, use this code which has worked for me:<?php$array= array("hello","fine","good","fine","hello","bye");$get_sorted_unique_array=array_values(array_unique($array));?>The above code returns an array which is both unique and sorted from zero.I had a problem with array_unique and multidimensional arrays ... Maybe there's a better way to do this, but this will work for any dimensional arrays.<?phpfunctionarrayUnique($myArray){ if(!is_array($myArray)) return$myArray; foreach ($myArrayas &$myvalue){$myvalue=serialize($myvalue); }$myArray=array_unique($myArray); foreach ($myArrayas &$myvalue){$myvalue=unserialize($myvalue); } return$myArray;}?>This is a script for multi_dimensional arrays<?phpfunctionremove_dup($matriz) {$aux_ini=array();$entrega=array(); for($n=0;$n<count($matriz);$n++) {$aux_ini[]=serialize($matriz[$n]); }$mat=array_unique($aux_ini); for($n=0;$n<count($matriz);$n++) {$entrega[]=unserialize($mat[$n]); } return$entrega;}?>recursive array unique for multiarrays<?phpfunctionsuper_unique($array){$result=array_map("unserialize",array_unique(array_map("serialize",$array))); foreach ($resultas$key=>$value) { if (is_array($value) ) {$result[$key] =super_unique($value); } } return$result;}?>Taking the advantage of array_unique, here is a simple function to check if an array has duplicate values.It simply compares the number of elements between the original array and the array_uniqued array.<?phpfunctionarray_has_duplicates(array$array){$uniq=array_unique($array); returncount($uniq) !=count($array);}?>another method to get unique values is :<?php$alpha=array('a','b','c','a','b','d','e','f','f');$alpha=array_keys(array_count_values($alpha));print_r($alpha);?>Output:Array ( [0] => a [1] => b [2] => c [3] => d [4] => e [5] => f )so .... my problem was multidimensional sort.<?php $new= array();$exclude= array(""); for ($i=0;$i<=count($attribs)-1;$i++) { if (!in_array(trim($attribs[$i]["price"]) ,$exclude)) {$new[] =$attribs[$i];$exclude[] =trim($attribs[$i]["price"]); } }?>Array $attribs is an array contaning arrays. Each array in the $attrib array consists in multiple fields (ex: name, lenght, price, etc.) to be more simpler in speech think that $attrib is the array resulted by a search sql query done by a visitator on your online shoopping website ... (so ... each array in the $attrib is a product :P) if you want to sort only the uniq results use the above or use this:<?php/* Our Array of products */$attribs[] = array("name"=>"Test Product 1","length"=>"42 cm","weight"=>"0,5 kg","price"=>"10 $","stock"=>"100", );$attribs[] = array("name"=>"Test Product 2","length"=>"42 cm","weight"=>"1,5 kg","price"=>"10 $","stock"=>"200", );/* The nice stuff */$new= array();$exclude= array(""); for ($i=0;$i<=count($attribs)-1;$i++) { if (!in_array(trim($attribs[$i]["price"]) ,$exclude)) {$new[] =$attribs[$i];$exclude[] =trim($attribs[$i]["price"]); } }print_r($new);// $new is our sorted array?>Have fun tweaking this ;)) i know you will ;))From Romania With LoveAnother way to 'unique column' an array, in this case an array of objects: Keep the desired unique column values in a static array inside the callback function for array_filter.Example:<?php/* example object */classmyObj{ public$id; public$value; function__construct($id,$value) {$this->id=$id;$this->value=$value; }}/* callback function */functionuniquecol($obj) { static$idlist= array(); if (in_array($obj->id,$idlist) ) returnfalse;$idlist[] =$obj->id; returntrue; }/* a couple of arrays with second array having an element with same id as the first */$list= array( newmyObj(1,1), newmyObj(2,100) );$list2= array( newmyObj(1,10), newmyObj(3,100) );$list3=array_merge($list,$list2);$unique=array_filter($list3,'uniquecol');print_r($list3);print_r($unique);?>In addition, use array_merge( $unique ) to reindex.As for PHP 7.1.12, this is the comparison between array_keys(array_flip()), array_flip(array_flip()), for each elimination and array_unique. The array_keys(array_flip()) is the fastest method to remove duplication values from a single dimension array:<?php$max=1000000;$arr=range(1,$max,3);$arr2=range(1,$max,2);$arr=array_merge($arr,$arr2);$time= -microtime(true);$res1=array_unique($arr);$time+=microtime(true);echo"<br>deduped to ".count($res1)." in ".$time;// deduped to 666667 in 0.78185796737671// memory used: 33558528$time= -microtime(true);$res2=array_flip(array_flip($arr));$time+=microtime(true);echo"<br><br>deduped to ".count($res2)." in ".$time;// deduped to 666667 in 0.072191953659058// memory used: 3774873$time= -microtime(true);$res3= array();foreach($arras$key=>$val) {$res3[$val] =true;}$res3=array_keys($res3);$time+=microtime(true);echo"<br /><br>deduped to ".count($res3)." in ".$time;// deduped to 666667 in 0.095494985580444// memory used: 33558528$time= -microtime(true);$res4=array_keys(array_flip($arr));$time+=microtime(true);echo"<br /><br>deduped to ".count($res4)." in ".$time;// deduped to 666667 in 0.05807900428772// memory used: 33558528Simple and clean way to get duplicate entries removed from a multidimensional array.<?php $multi_array=$multi_array[0];$multi_array=array_unique($multi_array);print_r($multi_array);?>I searched how to show only the de-duplicate elements from array, but failed. Here is my solution:<?phpfunctionarrayUniqueElements($array){returnarray_unique(array_diff_assoc($array1,array_unique($array1)));};?>Example:<?php$arr1= array('foo','bar','xyzzy','&','xyzzy','baz','bat','|','xyzzy','plugh','xyzzy','foobar','|','plonk','xyzzy','apples','&','xyzzy','oranges','xyzzy','pears','foobar');$result=arrayUniqueElements($arr1);print_r($result);exit;?>Output:Array([4] => xyzzy[12] => |[16] => &[21] => foobar)I found the simplest way to "unique" multidimensional arrays as follows:<?php$array= array('a'=> array(1,2),'b'=> array(1,2),'c'=> array(2,2),'d'=> array(2,1),'e'=> array(1,1),);$array=array_map('json_encode',$array);$array=array_unique($array);$array=array_map('json_decode',$array);print_r($array);?>As you can see "b" will be removed without any errors or notices.[Editor's note: please note that this will not work well with non-scalar values in the array. Array keys can not be arrays themselves, nor streams, resources, etc. Flipping the array causes a change in key-name]You can do a super fast version of array_unique directly in PHP, even faster than the other solution posted in the comments!Compared to the built in function it is 20x faster! (2x faster than the solution in the comments).<?phpfunctionsuperfast_array_unique($array) { returnarray_keys(array_flip($array));}?>This works faster for small and big arrays.Problem:I have loaded an array with the results of a databasequery. The Fields are 'FirstName' and 'LastName'.I would like to find a way to contactenate the twofields, and then return only unique values for thearray. For example, if the database query returnsthree instances of a record with the FirstName Johnand the LastName Smith in two distinct fields, I wouldlike to build a new array that would contain all theoriginal fields, but with John Smith in it only once.Thanks for: Colin CampbellSolution:<?php/** * The same thing than implode function, but return the keys so * * <code> * $_GET = array('id' => '4587','with' => 'key'); * ... * echo shared::implode_with_key('&',$_GET,'='); // Resultado: id=4587&with=key * ... * </code> * * @param string $glue Oque colocar entre as chave => valor * @param array $pieces Valores * @param string $hifen Separar chave da array do valor * @return string * @author memandeemail at gmail dot com */functionimplode_with_key($glue=null,$pieces,$hifen=',') {$return=null; foreach ($piecesas$tk=>$tv)$return.=$glue.$tk.$hifen.$tv; returnsubstr($return,1);}/** * Return unique values from a tree of values * * @param array $array_tree * @return array * @author memandeemail at gmail dot com */functionarray_unique_tree($array_tree) {$will_return= array();$vtemp= array(); foreach ($array_treeas$tkey=>$tvalue)$vtemp[$tkey] =implode_with_key('&',$tvalue,'='); foreach (array_keys(array_unique($vtemp)) as$tvalue)$will_return[$tvalue] =$array_tree[$tvalue]; return$will_return;}$problem=array_fill(0,3,array('FirstName'=>'John','LastName'=>'Smith'));$problem[] = array('FirstName'=>'Davi','LastName'=>'S. Mesquita');$problem[] = array('FirstName'=>'John','LastName'=>'Tom');print_r($problem);print_r(array_unique_tree($problem));?>An other solution to remove duplicates entries of a multi-dimensional array based on key…<?phpfunctionarray_unique_multi(array$array,string $key): array {$unique= []; foreach ($arrayas$v) { if (!array_key_exists($v[$key],$unique)) {$unique[$v[$key]] =$v; } } returnarray_values($unique);}// Usage$unique=array_unique_multi($users,'id');?>Or to preserve keys…<?phpfunctionarray_unique_amulti(array$array,string $key): array {$keys= [];$unique= []; foreach ($arrayas$k=>$v) { if (!isset($keys[$v[$key]])) {$keys[$v[$key]] =true;$unique[$k] =$v; } } return$unique;}?>Although array_unique is not intended to work with multi-dimensional arrays, it does on 5.2.9. However, it does not for 5.2.5. Beware.Here's the shortest line of code I could find/create to remove all duplicate entries from an array and then reindex the keys.<?php// Fruits, vegetables, and other food:$var= array('apple','banana','carrot','cat','dog','egg','eggplant','fish');$var=array_values(array_unique($var));?>The following is an efficient, adaptable implementation of array_unique which always retains the first key having a given value:<?phpfunctionarray_unique2(&$aray) {$aHash= array(); foreach ($arayas$key=> &$val) if (@$aHash[$val]++) unset ($aray[$key]);}?>It is also adaptable to multi dimensional arrays. For example, if your array is a sequence of (multidimensional) points, then in place of @$aHash[$val]++ you could use @$aHash[implode("X",$val)]++If you want to not have holes in your array, you can do an array_merge($aray) at the end.Csaba Gabor