Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Array Functions : array_unique

array_unique

Removes duplicate values from an array (PHP 4 >= 4.0.1, PHP 5)
array array_unique ( array array )

Example 286. array_unique() example

<?php
$input
= array("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 287. array_unique() and types

<?php
$input
= array(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"
} ?>

Related Examples ( Source code ) » array_unique



Code Examples / Notes » array_unique

kenrbnsn

Yet another Array_Unique for multi-demensioned arrays. I've only tested this on two-demensioned arrays, but it could probably be generalized for more, or made to use recursion.
This function uses the serialize, array_unique, and unserialize functions to do the work.
<?php
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);
}
?>


n@cho nospam cofrepuntonet

What if I only want the duplicated items, not the unique ones?
I tried to do it by using array_diff of an array and its unique, but it did not work (any help?); so I made this function with a relatively good efficiency:
<?php
function array_repeated($array) {
if(!is_array($array)) return false;
$repeated_values = Array();
$array_unique = array_unique($array);
if(count($array)-count($array_unique)) {
for($i=0;$i<count($array);$i++) {
if(!array_key_exists($i, $array_unique)) $repeated_values[] = $array[$i];
}
}
return $repeated_values;
}
?>
This function is based on the behaviour of the array_unique function that mantains the indexes of the array when deleting the item.


php

Try this:
array_flip(array_flip($array));
It gives the same result as the old array_unique()


mads dot rebsdorf

To unique an array in newer versions of php - i've found this snippet useful:
<?php
// $old[0] = 1
// $old[1] = 1
// $old[2] = 2
// $old[3] = 1
// $old[4] = 2
$new = array();
for($i=0;$i<count($old);++$i){
if(in_array($old[$i], $new) != "true"){
$new[] = $old[$i];
}
}
//$new now contains:
//
//$new[0] = 1
//$new[1] = 2
?>
/mads


kosi

to n@cho: $dup_values = array_intersect($array, array_unique($array));
I took the intersection instead of the difference.


martin

To get a list of the duplicated values in an array, array_unique isn't much help. Instead, use array_filter in conjunction with a callback function, as below:
<?php
$checkKeysUniqueComparison = create_function('$value','if ($value > 1) return true;');
$result = array_keys (array_filter (array_count_values($array), $checkKeysUniqueComparison));
?>
These two lines therefore will create $result, an array of duplicated values in the array $array, once each. E.g. the array
$array = array ("a", "b", "a", "b", "x", "y", "z", "x");
gives the result
Array([0] => a [1] => b [2] => x)


14-jan-2004 01:23

this simple function is similar based on to the function unique_multi_array posted by tru at ascribedata dot com, but will work for objects rather than arrays. use 2d objects. Its eg useful to work with mysql queries since in recent versions, the DISTINCT option in mysql selects will only work when selecting a single (not more) row.
eg.
foo_obj[0]:  name: 'tom', age: '20'
foo_obj[1]:  name: 'paul', age: '66'
foo_obj[2]:  name: 'tom', age: '23'
foo_obj = DistinctOn ($foo_obj, $item) will return
foo_obj[0]:  name: 'tom', age: '20'
foo_obj[1]:  name: 'paul', age: '66'
<?php
function DistinctOn ($obj, $item) {
  $out = array();
  $list = array();
  foreach ($obj as $key=>$so) {
      if (!in_array($so->$item, $list)) {
          $list[] = $so->$item;
          $out[$key] = $so;
      }
  }
  return $out;
}
?>


vary

This script will unique the array and count the times appearance.
find more information at http://php.scmtv.com/


laurynas dot butkus

This one would work with objects and arrays also.
<?php
function my_array_unique($array, $keep_key_assoc = false)
{
$duplicate_keys = array();
$tmp = array();
foreach ($array as $key=>$val)
{
// convert objects to arrays, in_array() does not support objects
if (is_object($val))
$val = (array)$val;
if (!in_array($val, $tmp))
$tmp[] = $val;
else
$duplicate_keys[] = $key;
}
foreach ($duplicate_keys as $key)
unset($array[$key]);

return $keep_key_assoc ? $array : array_values($array);
}
?>


xjazey

This is a solution to remove duplicate values from an array
<?php
$array[0] = "Yellow";
$array[1] = "Green";
$array[2] = "Yellow";
$array[3] = "Blue";
$array[4] = "Yellow";
$array = array_keys(array_flip($array));
//$array will output Yellow Green Blue
?>


agarcia

This is a script for multi_dimensional arrays
function remove_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;
}


mcmeijer

This is a recursive arrayUnique function for arrays of any dimension. (tested with 4-dimensional array)
The line '$newArray=deleteEmpty($newArray);' is optional and removes empty keys and values
<?php
function arrayUnique($myArray)
   {
   $newArray = Array();
   if (is_array($myArray))
       {
       foreach($myArray as $key=>$val)
           {
           if (is_array($val))
               {
               $val2 = arrayUnique($val);
               }
           else
               {
               $val2 = $val;
               $newArray=array_unique($myArray);
               $newArray=deleteEmpty($newArray);
               break;
               }
           if (!empty($val2))
               {
               $newArray[$key] = $val2;
               }
           }
       }
   return ($newArray);
   }
function deleteEmpty($myArray)
   {
   $retArray= Array();
   foreach($myArray as $key=>$val)
       {
       if (($key<>"") && ($val<>""))
           {
           $retArray[$key] = $val;
           }
       }
   return $retArray;
   }
?>


kay_rules

this function will return an array with unique value and proper key increment start from 0.
<?php
/*******************************/
function my_array_unique($somearray){
$tmparr = array_unique($somearray);
$i=0;
foreach ($tmparr as $v) {
$newarr[$i] = $v;
$i++;
}
return $newarr;
}
/********************************/
?>
eg:
<?php
$foo_arr[0] ='aa'
$foo_arr[1] ='bb'
$foo_arr[2] ='cc'
$foo_arr[3] ='bb'
$foo_arr[4] ='aa'
$foo_arr[5] ='dd'
?>
normal array_unique will return:
<?php
$foo_arr[0] ='aa';
$foo_arr[1] ='bb';
$foo_arr[2] ='cc';
$foo_arr[3] ='';
$foo_arr[4] ='';
$foo_arr[5] ='dd'
?>
my_array_unique will return:
<?php
$foo_arr[0] ='aa';
$foo_arr[1] ='bb';
$foo_arr[2] ='cc';
$foo_arr[3] ='dd'
?>


pulsarkowy

This function below will remove multiple values from array, remove 'empty' fields an also count how many times the given value occured.
it's rather slow and not 'elegant' but works.
usage:
$myarray=my_array_unique($myarray)
in return it produces an 3 fields array:
1st is index number, 2nd is the value, 3rd is counter.
function my_array_unique($tablica)
{
$tnum=count($tablica);
$i=1;
$k=1;
$t[1]['product']="";
$t[1]['count']=1;
while($i<=$tnum) {
 if (!array_multi_search($tablica[$i], $t)) {
   $t[$k]['product']=$tablica[$i];
   $t[$k]['count']=1;
   $k++;
 }
 else {
   $y=1;
   while ($y<=count($t)) {
     if ($t[$y]['product']==$tablica[$i])
       $t[$y]['count']++;
     $y++;
   }
 }
 
$i++;
}  
$tablica=$t;
return $tablica;
};
the function uses another function that i've found on the php.net site (i'm posting it only for informational reasons - i can't remember who wrote it):
function array_multi_search( $p_needle, $p_haystack )
  {
      if( !is_array( $p_haystack ) )
      {
          return false;
      }
      if( in_array( $p_needle, $p_haystack ) )
      {
          return true;
      }
      foreach( $p_haystack as $row )
      {
          if( array_multi_search( $p_needle, $row ) )
          {
              return true;
          }
      }
      return false;
  }


mod

The shortest way i found to remove duplicate array from a column,
For example if you parse Multiple XML sources, you can remove duplicate items that contain the same link.
<?PHP
function        remove_duplicate($array, $field)
{
 foreach ($array as $sub)
   $cmp[] = $sub[$field];
 $unique = array_unique($cmp);
 foreach ($unique as $k => $rien)
   $new[] = $array[$k];
 return $new;
}
?>


bisqwit

The recursivemakehash() in my previous post contained a flaw. Adding md5() to "return $tab;" fixes it making it now possible to distinguish array(0=>'x') from 'F4DBDF218CDC1683' etc.

jmw

The intersection won't work, since:
 intersection (['a','a','b','c'] , UNIQUE(['a','a','b','c']) )
=
 intersection (['a','a','b','c'], ['a','b','c'])
=
 ['a','a','b','c']
While you only want ['a'] or ['a','a'] to be the result. The only solution is to write your own function.


csaba

The following is an efficient, adaptable implementation of array_unique which always retains the first key having a given value:
<?php
function array_unique2(&$aray) {
   $aHash = array();
   foreach ($aray as $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


keneks

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.
function array_search_dups($array)
{
$dup_array = $array;
$dup_array = array_unique($dup_array);
if(count($dup_array) != count($array))
{
return TRUE;
}
else
{
return FALSE;
}
}


tsikano

Suggestion for being able to use array_unique on array of arrays/objects:
<?php
foreach ($arrayOfArrays as $key=>$value) {
 $arrayOfArrays[$key] = "'" . serialize($value) . "'";
}
$arrayOfArrays = array_unique($arrayOfArrays);
foreach ($arrayOfArrays as $key=>$value) {
 $arrayOfArrays[$key] = unserialize(trim($value, "'"));
}
?>


geuis dot teses

Sorry to repost this but it was helpful and took a while to find all the way down.
Ric
05-Apr-2005 09:44
A very simple way of getting rid of duplicate entries and re-indexing with key starting at 0:
  $temp=array_unique($main);
  $main=array_values($temp);


mew

Smaller version for PHP5
<?php
# array array_unique_save (array array [, bool preserve_keys] )
function array_unique_save ($a, $pk = true) {
$a = array_diff_key($a, array_unique($a));
return ($pk ? $a : array_values($a));
}
?>


logicearth

Should have thought of this sooner. x.x
<?php
function array_unique_save_php4 ($a, $pk = true) {
$t = array_keys(array_unique($a));
foreach ($t as $k) { unset($a[$k]); }
return ($pk ? $a : array_values($a));
}
?>


matthew_dean

Re: Useful comments from jllamas@bal.com.mx
If you are using a numerically indexed array and you want to make it unique but *with* consecutive indices, you can use array_values(array_unique($myArray));


memandeemail

Problem:
I have loaded an array with the results of a database
query.  The Fields are 'FirstName' and 'LastName'.
I would like to find a way to contactenate the two
fields, and then return only unique values for the
array.  For example, if the database query returns
three instances of a record with the FirstName John
and the LastName Smith in two distinct fields, I would
like to build a new array that would contain all the
original fields, but with John Smith in it only once.
Thanks for: Colin Campbell
Solution:
/**
* 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
*/
function implode_with_key($glue = null, $pieces, $hifen = ',') {
 $return = null;
 foreach ($pieces as $tk => $tv) $return .= $glue.$tk.$hifen.$tv;
 return substr($return,1);
}
/**
* Return unique values from a tree of values
*
* @param array $array_tree
* @return array
* @author memandeemail at gmail dot com
*/
function array_unique_tree($array_tree) {
 $will_return = array(); $vtemp = array();
 foreach ($array_tree as $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));


burno

Or just do a usort($myArray,"return -1"); after the usage of array_unique

justin

OK, so here's my version that maintains index integrity:
function array_unique($array)
{
$out = array();

// loop through the inbound
foreach ($array as $key=>$value) {
// if the item isn't in the array
if (!in_array($value, $out)) {
// add it to the array
$out[$key] = $value;
}
}

return $out;
}


n@cho nospam cofrepuntonet

Note that array_unique preserves the keys, even if the array is not associative:
$values = Array("john@hotmail.com", "peter@hotmail.com", "will@hotmail.com", "john@hotmail.com", "laura@hotmail.com", "mariah@hotmail.com");
echo "
".count($values)." values.
";
var_dump($values);
$unique_values = array_unique($values);
echo "
".count($unique_values)." unique values.
";
var_dump($unique_values);
RESULT:
6 values.
array(6) {
 [0]=>
 string(16) "john@hotmail.com"
 [1]=>
 string(17) "peter@hotmail.com"
 [2]=>
 string(16) "will@hotmail.com"
 [3]=>
 string(16) "john@hotmail.com"
 [4]=>
 string(17) "laura@hotmail.com"
 [5]=>
 string(18) "mariah@hotmail.com"
}
5 unique values.
array(5) {
 [0]=>
 string(16) "john@hotmail.com"
 [1]=>
 string(17) "peter@hotmail.com"
 [2]=>
 string(16) "will@hotmail.com"
 [4]=>
 string(17) "laura@hotmail.com"
 [5]=>
 string(18) "mariah@hotmail.com"
}
$unique_values[3] is missing. Use array_merge or array_values if you need the index to be linear.


matt

Note that
<?php
array_unique($anyarray);
?>
does not do anything, unlike other array functions such as
<?php
sort($anyarray);
?>
You have to use something like:
<?php
$anyarray = array_unique($anyarray);
?>


sterba

Maybe this will come handy for PHP3 users:
<?php
for ($a = 0; $a < $arraylength; $a++){
   if (($a > 0)&&($array[$a] <> $array[$a-1]))
       $uniquearray[$a] = $array[$a];
   $a++;
}
?>
You can even skip the $a>0 test, I believe... not bulletproof, but much shorter.


arr1

Just to note that array_unique, treats null values as none unique values. So if your using array_unique to detect duplicate values it will also detect multiple null values.

trigger

Just a simple implementation for JavaScript:
function array_unique(thearray)
{
thearray.sort();
//reset($thearray);
newarray = new Array();
for (n=0;n<thearray.length;n++)
{
unique=1;//by default
for(nn=0;nn<newarray.length;nn++)
if (thearray[n] == newarray[nn])
{
unique=0;//already exists
break;
}
if(unique)//dont exists
newarray.push(thearray[n]);
}
return newarray;
}


jllamas

It seems that array_unique creates an exact copy of the original array and then elimitates duplicate values. It does NOT change the "internal references" of the array. For example:
<?php
   $test_alfa = array();
   $test_alfa[0] = "aa";
   $test_alfa[1] = "aa";
   $test_alfa[2] = "aa";
   $test_alfa[3] = "bb";
   $test_alfa[4] = "aa";
   $test_alfa[5] = "bb";
   $test_alfa[6] = "cc";
   $test_alfa[7] = "bb";
 
   $test_beta= array_unique($test_alfa);
   $numValues = count($test_beta);
   for ($i = 0 ; $i <= 7 ; $i++)
      echo("test_beta[$i] = $test_beta[$i]
");
   echo ("Number of elements in test_beta = $numValues ");
?>
will give you the following output:
test_beta[0] =
test_beta[1] = aa
test_beta[2] =
test_beta[3] =
test_beta[4] =
test_beta[5] = bb
test_beta[6] = cc
test_beta[7] =
Number of elements in test_beta = 3
The point is that you won't get the output you'd expect if you think that the values of the non duplicate elements are located in the first three array locations.
   $numValues = count($test_beta);
   for ($i=0;$i<=$numValues; $i++)
      echo("test_beta[$i] = $test_beta[$i]
");
   echo ("Number of elements in test_beta = $numValues ");
will give you:
test_beta[0] =
test_beta[1] = aa
test_beta[2] =
Number of elements in test_beta = 3
Hope that saves u some debugging time!


kokos

In response to muddmonkey@harveyMcoldotedu (yeah, i know i'm a bit too late :D )
In your example you're using the "flip-flip" AFTER doing the array_unique() already. That's why it is so fast. ;)


jacob dot bates

In response to muddmonkey's flip-flip method, i would like to note that using this method as-is leaves the array with gaps.  For example, if we have an array like this:
Array
(
   [0] => 1
   [1] => 1
   [2] => 1
)
And you apply the flip-flip method, you get this:
Array
(
   [2] => 1
)
If you apply the array_merge function to the result, it closes these gaps without seriously sacrificing performance.  I wrote some test code that would result in a unique array that has 10,000 elements so that the impact of array_merge was more evident.  Here is my test code:
function microtime_float(){ //timing (stolen from muddmonkey)
  list($usec, $sec) = explode(" ", microtime());
  return ((float)$usec + (float)$sec);
}
//make an array and fill it up
$final=array();
for($i=0;$i<50000;$i++){
  $final[]=$i%10000; //make sure the unique array has 10000 elements
}
//try flip-flip
$start1 = microtime_float();
array_flip(array_flip($final));
$stop1=microtime_float();
echo($stop1-$start1.' (flip-flip)
');
//try my flip-flip-merge
$start2=microtime_float();
array_merge(array_flip(array_flip($final)));
$stop2=microtime_float();
echo($stop2-$start2.' (flip-flip-merge)<br />');
//try array_unique
$start3=microtime_float();
array_unique($final);
$stop3=microtime_float();
echo($stop3-$start3.' (array_unique)<br />');
Here was the result:
0.14240193367004 (flip-flip)
0.18947601318359 (flip-flip-merge)
3.7108051776886 (array_unique)
As you can see, flip-flip-merge slows it down a little, but both are still way faster than array_unique.


idefix

in reply to memandeemail at gmail dot com:
imo it would be easier to do these things in your SQL statement.
ex.:
SELECT na1.FirstName, na1.LastName
FROM names na1, names na2
WHERE na1.FirstName = na2.FirstName
AND na1.LastName = na2.LastName
AND na1.id < na2.id;


a dot fotoglidis

In addition to brettz9's remove_dups:
This one will actually take a multi-dimensional array and return it minus the duplicates in regard to the specified element of the inner arrays.
<?php
/*
 Initialising new array to the first element of the given array.
 Check whether current element in initial array has already been added to new array.
 If yes break to save us some time. If no, then add current element to new array.
*/
function remove_dups($array, $row_element) {
$new_array[0] = $array[0];
foreach ($array as $current) {
$add_flag = 1;
foreach ($new_array as $tmp) {
if ($current[$row_element]==$tmp[$row_element]) {
$add_flag = 0; break;
}
}
if ($add_flag) $new_array[] = $current;
}
return $new_array;
} // end function remove_dups
?>
______________________________________________
EXAMPLE
<?php
   $array[0] = array('Charles','Wade',233);
   $array[1] = array('Charles','Watson',234);
   $array[2] = array('Tom','Wade',235);
   $array = remove_dups($array,0);
?>
The above example will output:
Array
(
   [0] => Array ([0] => 'Charles' [1] => 'Wade' [2] => 233)
   [1] => Array ([0] => 'Tom' [1] => 'Wade' [2] => 235)
)
<?php
remove dups($array,1);
?>
will output:
Array
(
   [0] => Array ([0] => 'Charles' [1] => 'Wade' [2] => 233)
   [1] => Array ([1] => 'Charles' [1] => 'Watson' [2] => 234)
)
At each case it removes all inner arrays that have a duplicate in the specified position and keeps the first inner array only.


juggler

in addition to bisqwit:
in some cases you can simply use serialize instead of recursivemakehash().
<?php
function array_unique2($input) {
$tmp = array();
foreach($input as $a => $b)
$tmp[$a] = serialize($b);
$newinput = array();
foreach(array_unique($tmp) as $a => $b)
$newinput[$a] = $input[$a];
return $newinput;
}
?>
Have fun
Juggler


muddmonkey@harveymcoldotedu

If you're doing numeric arrays etc. I found flip-flip to work much better than array_unique:
<?PHP
   function microtime_float(){ //timing
      list($usec, $sec) = explode(" ", microtime());
      return ((float)$usec + (float)$sec);
   }
   //make an arry and fill it up
   $final=array();
   for($i=0;$i<50000;$i++){
       $final[]=$i%13; //make sure there are some dupes
   }
   //try array unique
   $start1 = microtime_float();
   array_unique($final);
   $stop1=microtime_float();
   echo($stop1-$start1.'
');
   //try my flip-flip
   $start2=microtime_float();
   array_flip(array_flip($final));
   $stop2=microtime_float();
   echo($stop2-$start2);
?>
Running this with only ints in the array (as above) I get runtimes such as:
1.6195669174194 (using unique)
0.017037868499756 (using flip flip)
which is two orders of magnitude faster!
Appending a string:
($final[]='test'.$i%13;)
gives:
0.42909598350525 (using unique)
0.023258924484253 (using flip-flip)
Which is not AS great, but still 20x faster than unique.
In both cases the flip-flip seems to use less memory than the unique.
Granted the flip-flip doesn't work for all cases, but if you're doing simple stuff like this, the flip-flip will give you better run times.
~JF


patrikg

If you need to have the keys of the duplicates in an array returned, you may find this function useful:
<?php
function unique_events($array){
//checks $array for duplicate values and returns an
       //array containing the keys of duplicates
$count= array_intersect_assoc($array, array_flip( array_count_values($array)));
foreach($array as $key=>$value){
if (in_array($value,$count)){
$return[$value][]=$key;
}
}
return $return;
}
?>
Example:
Input:
Array
(
   [0] => 44
   [1] => 23
   [2] => 23
   [3] => 23
   [4] => 9
   [5] => 9
   [6] => 9
   [7] => 9
   [8] => 9
   [9] => 9
   [10] => 9
   [11] => 9
)
Function returns:
Array
(
   [23] => Array
       (
           [0] => 1
           [1] => 2
           [2] => 3
       )
   [9] => Array
       (
           [0] => 4
           [1] => 5
           [2] => 6
           [3] => 7
           [4] => 8
           [5] => 9
           [6] => 10
           [7] => 11
       )
)


brettz9

If you have a multi-dimensional array and wish to remove duplicates from a particular "column" as well as the corresponding values in the other "columns", you might find the following helpful.
<?php
function remove_dups($array, $index) {
$array_count = count($array);
$array_count_inner = count($array[$index]);
for ($i=0; $i<$array_count_inner; $i++) {
for ($j=$i+1; $j<$array_count_inner; $j++) {
if ($array[$index][$i]==$array[$index][$j]) {
for ($k=0; $k<$array_count; $k++) {
unset($array[$k][$i]);
} // end for
} // end if
} // end for
} // end for
return $array;
} // end function remove_dups
?>


christoph ziegenberg

If the array key is a string it might be important to keep it although the value is the same (as I need it at the moment). So I wrote a function which also returns array elements which have the same value but different string keys.
function array_unique_numeric ($arr)
{
   $str = $int = array();
   foreach(array_keys($arr) as $key) {
       ${(is_int($key)?'int':'str')}[$key] = $arr[$key];
   }
   return array_merge($str, array_unique($int));
}
// typical array after an array_merge()...
$array = array("a" => "green", "b" => "brown", "c" => "blue", "red", "d" => "green", "yellow", "red");
print_r(array_unique($array));
// Array
// (
//     [a] => green
//     [b] => brown
//     [c] => blue
//     [0] => red
//     [1] => yellow
// )
print_r(array_unique_numeric($array));
// Array
// (
//     [a] => green
//     [b] => brown
//     [c] => blue
//     [d] => green
//     [0] => red
//     [1] => yellow
// )


davin

I used the code submitted by "agarcia" regarding multi-dimensional arrays but keys with no data were still there. I've just added a line to completely unset the redondant part of the array so it is now acting like array_unique.
<?php
function remove_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]);
  }
  foreach ($entrega as $key => $row){
     if (!is_array($row)) { unset($entrega[$key]); }
  }
  return $entrega;
}
?>
Thanks!
Davin Baragiotta


lucas.bickel

I quite like the following code for making multidimensional arrays unique:
foreach ($arrAddressList AS $key => $arrAddress) {
   $arrAddressList[$key] = serialize($arrAddress);
}
$arrAddressList = array_unique($arrAdressList);
foreach ($arrAddressList AS $key => $strAddress) {
   $arrAddressList[$key] = unserialize($strAddress);
}
This gets me a unique array while not minding wether the the original array contains arrays or just strings (or whatever...).


spunk

I needed a way of retaining the original array's keys in the new, unique array. I came up with this. It works for my purposes but may need refinement.
function my_array_unique($somearray)
{
asort($somearray);
reset($somearray);
$currentarrayvar = current($somearray);
foreach ($somearray as $key=>$var)
{
if (next($somearray) != $currentarrayvar)
{
$uniquearray[$key] = $currentarrayvar;
$currentarrayvar = current($somearray);
}
}
reset($uniquearray);
return $uniquearray;
}


geuis dot teses

Here's the shortest line of code I could find/create to remove all duplicate entries from an array and then reindex the keys.
//$var is an array. This example its one-dimensional. Your most basic kind of array.
$var = array_values(array_unique($var));


moose

Here's a little function I wrote that's similar to array_unique, for PHP3 users.  It actually removes duplicated elements, but only works for 1 dimensional arrays.  It also doesn't return a value, it changes the input array:
<?php
function array_unique(&$thearray)
{sort($thearray);
reset($thearray);
$newarray = array();
$i = 0;
$element = current($thearray);
for ($n=0;$n<sizeof($thearray);$n++)
{if (next($thearray) != $element)
 {$newarray[$i] = $element;
  $element = current($thearray);
  $i++;
 }
}
$thearray = $newarray;
}
?>


tru

Here's a function to make a multi-dimensional array have only DISTINCT values for a certain "column". It's like using the DISTINCT parameter on a SELECT sql statement.
<?php
function unique_multi_array($array, $sub_key) {
$target = array();
$existing_sub_key_values = array();
foreach ($array as $key=>$sub_array) {
if (!in_array($sub_array[$sub_key], $existing_sub_key_values)) {
$existing_sub_key_values[] = $sub_array[$sub_key];
$target[$key] = $sub_array;
}
}
return $target;
}
?>


ome_henk

For people looking at the flip flip method for getting unique values in a simple array. This is the absolute fastest method:
$unique = array_keys(array_flip($array));
It's marginally faster as $unique = array_merge(array_flip(array_flip($array)));
And it's marginally slower as $unique array_flip(array_flip($array)) which leaves gaps.
It's still about twice as fast or fast as array_unique.
This tested on several different machines with 100000 random arrays. All machines used a version of PHP5.


wernerlistas

Following the code copies of a little function I've wrote that actually works with multidimensional arrays.
It also resets the array indexes.
<?php
if ( !function_exists( "arrayUnique" ) ){
   function arrayUnique ( $rArray ){
       $rReturn = array ();
       while ( list( $key, $val ) = each ( $rArray ) ){
           if ( !in_array( $val, $rReturn ) )
           array_push( $rReturn, $val );
       }
       return $rReturn;
   }
}
?>


rein

Following code copies unique values from MyArray to TempArray.
Then copies non-empty elements from TempArray to UniqueArray.
Not the most elegant solution, but it works.
<?php
$TempArray = array_unique($MyArray);
while (list($index,$data)=each($TempArray)) {
     if (isempty($data)) {
         $UniqueArray[$index]=$data;
     }
}
?>


cz12

Check for duplicates in an array (as opposed to removing them):
<?php
if (array_unique($array) != $array)
{
   echo "Duplicate located in array.";
}
?>


mnbayazit

case insensitive
<?php
function array_iunique($array) {
return array_intersect_key($array,array_unique(
                array_map(strtolower,$array)));
}
?>


deigo

Before I found the mysql distinct I had to make a nicer array from the keys/values that I got from array_unique so.
$groups=array_unique($groups);
$newgroup[0]=reset($groups);
for ($x=1;$x<sizeof($groups);$x++)
{
$newgroup[$x]=next($groups);
}


az

Attention!
If you use array_unique be aware of data-types! (I spent hours of debugging because of that ...).
For example, if you've got an array containing a '3' as number and another '3' as string it won't be eliminated by array_unique.
An Example where this can happen, without really thinking about it:
I've got an article-list with product-numbers where the third and fourth digit is the code for the producer. So I read in the file an process it line by line and put each producer-code into an array:
------------------------------
<?php
$i=0;
while($line = fgets($csv, 10000) {
// splitting the line, product_no is the first part:
$data = explode(";", $line);
// putting the producer_code into an array:
$producer_id[$i] = trim(substr($data[0], 2, 2));
// make a special exception:
if(trim(substr($data[0], 2, 2)) == 40) {
$producer_id[$j] = '30';
}
// in the above line if you leave the 30 without the ''
// array_unique won't work!
$i++;
}
$producer_ids = array_values(array_unique($producer_id));
?>
-------------------------------
Result is to have all producer-ID's in an array without dupes.


ailanto

As in 4.0.3pl1, array_unique() in 4.0.5 returns the *last* key encountered for every value!

bisqwit

array_unique() doesn't return anything useful if your input is an
array containing arrays. This function overcomes the problem.
Any level of recursions is possible here. If the input is a plain
array, the result is compatible with array_unique() result.
<?php
function recursivemakehash($tab)
{
 if(!is_array($tab))
   return $tab;
 $p = '';
 foreach($tab as $a => $b)
   $p .= sprintf('%08X%08X', crc32($a), crc32(recursivemakehash($b)));
 return $p;
}
function array_unique2($input)
{
 $dumdum = array();
 foreach($input as $a => $b)
   $dumdum[$a] = recursivemakehash($b);
 $newinput = array();
 foreach(array_unique($dumdum) as $a => $b)
   $newinput[$a] = $input[$a];
 return $newinput;
}
?>


webcreator

array_unique function starts its comparation from beginning and pop the key off if there is more values inside array. The last one remains. But i needed to hold priority of the order of values and let the first one in.
Here is my easy solution:
##---
function my_array_unique($from)
{
for ($i=count($from);$i>1;$i--)
{
$last = $from[$i];
$from[$i] = "";
if (!in_array($last,$from))
$from[$i]=$last;
}
return array_unique($from);
}
# One empty value remains in array.
# But its very easy to separate it while using output array.


passtschu

array_unique for multidimensional arrays. similar to the DISTINCT in SQL function.
the function can group, sum and count keys
<?PHP
/*
$array - nothing to say
$group_keys - columns which have to be grouped - can be STRING or ARRAY (STRING, STRING[, ...])
$sum_keys - columns which have to be summed - can be STRING or ARRAY (STRING, STRING[, ...])
$count_key - must be STRING - count the grouped keys
*/
function array_distinct ($array, $group_keys, $sum_keys = NULL, $count_key = NULL){
 if (!is_array ($group_keys)) $group_keys = array ($group_keys);
 if (!is_array ($sum_keys)) $sum_keys = array ($sum_keys);
 $existing_sub_keys = array ();
 $output = array ();
 foreach ($array as $key => $sub_array){
   $puffer = NULL;
   #group keys
   foreach ($group_keys as $group_key){
     $puffer .= $sub_array[$group_key];
   }
   $puffer = serialize ($puffer);
   if (!in_array ($puffer, $existing_sub_keys)){
     $existing_sub_keys[$key] = $puffer;
     $output[$key] = $sub_array;
   }
   else{
     $puffer = array_search ($puffer, $existing_sub_keys);
     #sum keys
     foreach ($sum_keys as $sum_key){
       if (is_string ($sum_key)) $output[$puffer][$sum_key] += $sub_array[$sum_key];
     }
     #count grouped keys
     if (!array_key_exists ($count_key, $output[$puffer])) $output[$puffer][$count_key] = 1;
     if (is_string ($count_key)) $output[$puffer][$count_key]++;
   }
 }
 return $output;
}
?>


snoyes+php

Another way to get unique objects/arrays:
<?php
function my_array_unique($array) {
   return array_intersect_key($array, array_unique(array_map('serialize', $array)));
}
?>


webmaster

Another 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 */
class myObj {
 public $id;
 public $value;
 function __construct( $id, $value ) {
   $this->id = $id;
   $this->value = $value;
 }
}
/* callback function */
function uniquecol( $obj ) {
 static $idlist = array();
 if ( in_array( $obj->id, $idlist ) )
   return false;
 $idlist[] = $obj->id;
 return true;    
}
/* a couple of arrays with second array having an element with same id as the first */
$list  = array( new myObj( 1, 1  ), new myObj( 2, 100 ) );
$list2 = array( new myObj( 1, 10 ), new myObj( 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.


danny

An updated version of webcreators script that fixes a notice error about an undefined index and removes blank array value.
<?php
function my_array_unique($from) {
for ($i=count($from)-1;$i>1;$i--) {
   $last = $from[$i];
    $from[$i] = false;
   if (!in_array($last,$from)) {
$from[$i]=$last;  
}
   }
$from = array_unique($from);
$from = array_slice($from,0,count($from)-1);
return $from;
}
?>


ric

A very simple way of getting rid of duplicate entries and re-indexing with key starting at 0:
$temp=array_unique($main);
$main=array_values($temp);


az

@lefeuvrenicolas
Use the above mentioned combination with "array_values" - then it works.
So do it like this:
--------------------
<?php
$truc = array("l810u00","l810u00","l810q00");
$machin = array_values(array_unique($truc));
for($i=0;$i < count($machin) ; $i++){
echo $machin[$i]."\n";
}
?>
--------------------
But it is strange anyway ...


bitmore.co.kr

//Modify
Object Unique
<?php
class foo {
var $_name;
var $_age;
function foo($name,$age=NULL) { $this->_name = $name; $this->_age = $age; }
//function get() { return $this->_name; }
//function set($name,$age=NULL) { $this->_name = $name; $this->_age = $age; }
}
function DistinctOn ($obj, $item) {
$out = array();
$list = array();
foreach ($obj as $key=>$so) {
if (!in_array($so->$item, $list)) {
echo "key = $key,so = $so,item = $item,IFlist = ";print_r($list);echo "
";
$list[] = $so->$item;//°ËÁõ¹è¿­
$out[$key] = $so;
}
echo "Forlist = ";print_r($list);echo "
";
}
return $out;
}
$foo_obj[0] = new foo('tom',20);
$foo_obj[1] = new foo('paul',66);
$foo_obj[2] = new foo('tom',23);
$item = '_name';
$result = DistinctOn ($foo_obj, $item);
while(list($k,$v) = each($result)) {
print "K = ";print_r($k);
print ",V = ";print_r($v);
print "
";
}
//key = 0,so = Object,item = _name,IFlist = Array ( ) ,Forlist = Array ( [0] => tom )
//key = 1,so = Object,item = _name,IFlist = Array ( [0] => tom ) ,Forlist = Array ( [0] => tom [1] => paul )
//Forlist = Array ( [0] => tom [1] => paul )
//K = 0,V = foo Object ( [_name] => tom [_age] => 20 )
//K = 1,V = foo Object ( [_name] => paul [_age] => 66 )
print "
";
$item = '_age';
$result = DistinctOn ($foo_obj, $item);
while(list($k,$v) = each($result)) {
print "K = ";print_r($k);
print ",V = ";print_r($v);
print "
";
}
//key = 0,so = Object,item = _age,IFlist = Array ( ) ,Forlist = Array ( [0] => 20 )
//key = 1,so = Object,item = _age,IFlist = Array ( [0] => 20 ) ,Forlist = Array ( [0] => 20 [1] => 66 )
//key = 2,so = Object,item = _age,IFlist = Array ( [0] => 20 [1] => 66 ) ,
// Forlist = Array ( [0] => 20 [1] => 66 [2] => 23 )
//K = 0,V = foo Object ( [_name] => tom [_age] => 20 )
//K = 1,V = foo Object ( [_name] => paul [_age] => 66 )
//K = 2,V = foo Object ( [_name] => tom [_age] => 23 )
?>


memandeemail

/**
* Removes duplicate keys from an array
*
* @param array $array
* @return array
*/
function array_unique_key($array) {
$result = array();
foreach (array_unique(array_keys($array)) as $tvalue) {
$result[$tvalue] = $array[$tvalue];
}
return $result;
}


array_unique_full

<?php
function array_unique_FULL($array) {
 foreach($array as $k => $v) {
   if (is_array($v)) {
     $ret = array_unique_FULL(array_merge($ret, $v));
   } else {
     $ret[$k] = $v;
   }
 } //for
 return array_unique($ret);
}
?>
Array
(
   [0] => js/pt.js
   [1] => js/selectfile.js
   [2] => js/pt.js
   [3] => js/proyecto.js
   [4] => Array
       (
           [0] => Array
               (
                   [0] => js/selectfile.js
                   [1] => js/selectfile.js
                   [2] => js/y otro mas.js
               )
           [1] => q se yo
       )
)
go array_unique_FULL()!!!!
Array
(
   [0] => js/pt.js
   [1] => js/selectfile.js
   [3] => js/proyecto.js
   [6] => js/y otro mas.js
   [5] => q se yo
)


uditsawhney

<?php
//Fn for array_unique column-wise for multi-dimensioanl array without losing keys | Start
function array_uniquecolumn($arr)
{
$rows   = sizeof($arr);
$columns = sizeof($arr[0]);

$columnkeys = array_keys($arr[0]);

for($i=0; $i<$columns; $i++)
{
for($j=0;$j<$rows;$j++)
{
for($k = $j+1; $k<$rows; $k++)
{
if($arr[$j][$columnkeys[$i]] == $arr[$k][$columnkeys[$i]])
$arr[$k][$columnkeys[$i]] = "";
}
}

}
return ($arr);
}
//Fn for array_unique column-wise for multi-dimensioanl array without losing keys | Stop
$arrUGCourse[]= array(  "CTR" => "1",
                       "UGCOURSE"=>"ABC",
                       "TSINITIATE"=>"540",
                       "COUNT"=>"34",
                       "ENTRY_DT"=>"2006-05-01",
                       "CUMULATIVE"=> 44);

$arrUGCourse[]= array(  "CTR" => "2",
                       "UGCOURSE"=>"ABC",
                       "TSINITIATE"=>"5401",
                       "COUNT"=>"341",
                       "ENTRY_DT"=>"2006-05-11",
                       "CUMULATIVE"=> 44);
print_r(array_uniquecolumn($arrUGCourse));
?>


cdblog

<?php
/**
* @param string
* @return array
* @author Cocol
* @desc generate unique keywords
* for more detail please visit http://php.clickz.cn/articles/array/array_unique.html
*/
function keyword_unique($url = "") {
$unique =  array(
'words' => array(),
'times' => array(),
);

   $buffer = @file_get_contents($url);
   $words1 = str_word_count(strtolower(strip_tags($buffer)),1);    
   $unique['words'] = array_unique($words1);
   foreach ($words1 as $key=>$val) {    
    if (!in_array($val,$unique['words'])) {    
    $unique['times'][] = 1;
    } else {
    $i = array_search($val,$unique['words']);
    $unique['times'][$i] += 1;
    }
   }
   array_multisort($unique['times'],SORT_DESC,$unique['words']);
   return $unique;
}
$keywords = keyword_unique("http://php.clickz.cn/");
print_r($keywords);
?>


29-aug-2002 10:39

<?
$truc = array("l810u00","l810u00","l810q00");
$machin = array_unique($truc);
for($i=0;$i < count($machin) ; $i++){
print $machin[$i]."
";
}
?>
result :
l810u00
This is not strange: $machin (as returned by array unique), contains "l810u00" either in key[0] or key[1] but not both (the key depends on the ersion of PHP), and "l810q00" in key[2].
The returned array has TWO elements so count($machin)==2.
The returned array has a hole in it, and you're not displaying its full content. You could verify it by using this display loop instead:
foreach($machine as $key=>$value){
print '[' . $key . '] => ' . $value . '
";
}
result:
[0] => l810q00
[2] => l810u00
(the first line may display [1] instead of [0] for PHP 4.0.1p3, but you'll get the same order of values and two lines, as expected). When calling array_values() on the result, you're building a new array with the same values in the same order, but with renumbered keys (without holes in numeric keys).


eltehaem

>array_unique() will keep the first key encountered
>for every value, and ignore all following keys.
This is true only in PHP 4.0.4pl1, i.e. the code below:
<?php
$temp = Array ('pl', 'pl', 'en', 'en', 'cz', 'de', 'en', 'pl');
print_r($temp);
print_r(array_unique($temp));
?>
Will produce this output:
Array
(
   [0] => pl
   [1] => pl
   [2] => en
   [3] => en
   [4] => cz
   [5] => de
   [6] => en
   [7] => pl
)
Array
(
   [0] => pl
   [2] => en
   [4] => cz
   [5] => de
)
And in PHP 4.0.3pl1 will produce this output:
Array
(
   [0] => pl
   [1] => pl
   [2] => en
   [3] => en
   [4] => cz
   [5] => de
   [6] => en
   [7] => pl
)
Array
(
   [4] => cz
   [5] => de
   [6] => en
   [7] => pl
)
This little function resolves the problem:
<?php
function my_array_unique(&$old){
$new = array();
foreach($old as $key => $value){
if(!in_array($value, $new)) $new[$key] = $value;
}
return $new;
}
?>


sneze

$users = array_unique($online_users);
foreach($users as $value){
echo $value;
}
saved my day


Change Language


Follow Navioo On Twitter
array_change_key_case
array_chunk
array_combine
array_count_values
array_diff_assoc
array_diff_key
array_diff_uassoc
array_diff_ukey
array_diff
array_fill_keys
array_fill
array_filter
array_flip
array_intersect_assoc
array_intersect_key
array_intersect_uassoc
array_intersect_ukey
array_intersect
array_key_exists
array_keys
array_map
array_merge_recursive
array_merge
array_multisort
array_pad
array_pop
array_product
array_push
array_rand
array_reduce
array_reverse
array_search
array_shift
array_slice
array_splice
array_sum
array_udiff_assoc
array_udiff_uassoc
array_udiff
array_uintersect_assoc
array_uintersect_uassoc
array_uintersect
array_unique
array_unshift
array_values
array_walk_recursive
array_walk
array
arsort
asort
compact
count
current
each
end
extract
in_array
key
krsort
ksort
list
natcasesort
natsort
next
pos
prev
range
reset
rsort
shuffle
sizeof
sort
uasort
uksort
usort
eXTReMe Tracker