240

How can I remove duplicate values from an array in PHP?

HamZa
  • 14,671
  • 11
  • 54
  • 75
Ian
  • 11,920
  • 27
  • 61
  • 77
  • 1
    It depends on context. Do you have a flat array or a multidimensional array? Are all of your values scalar? Might your values contain float/double values? Do you want to keep the first or last occurring duplicates? Do you need to reindex the array? (nimey sara thomas seems to think this is a pertinent step for some odd reason) Where is your sample input? What is your exact desired result? [mcve]s make the best questions. This question needs clarity to avoid receiving answers that are unsuitable or even wrong. – mickmackusa May 20 '23 at 22:44
  • 1
    What type of data is in the array? Is it direct data or more arrays? If direct data, what kind/type of data? The answer depends heavily on that information. – TylerH May 22 '23 at 20:38

22 Answers22

372

Use array_unique() for a one-dimensional array. From the PHP manual:

Takes an input array and returns a new array without duplicate values.

Note that keys are preserved. If multiple elements compare equal under the given flags, then the key and value of the first equal element will be retained.

Note that array_unique() is not intended to work on multi dimensional arrays.

Example:

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

If you want the values re-indexed, in addition, you should apply array_values.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Paige Ruten
  • 172,675
  • 36
  • 177
  • 197
83

Use array_values(array_unique($array));

array_unique: for unique array array_values: for reindexing

FelixSFD
  • 6,052
  • 10
  • 43
  • 117
nimey sara thomas
  • 1,035
  • 8
  • 5
  • 8
    +1 `array_unique` returns an object with key and value pairs AND `array_values` return only values as an array. – narainsagar Sep 21 '18 at 17:16
  • @narainsagar (and the 8 comment upvoters)... What?!? `array_unique()` DEMANDS an array as the first parameter. And `array_values()` DEMANDS an array as its parameter. If you are dealing with an object, then this code will break. Please do not mislead researchers with untruths. – mickmackusa May 20 '23 at 22:38
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 )
chim
  • 8,407
  • 3
  • 52
  • 60
21
$result = array();
foreach ($array as $key => $value){
  if(!in_array($value, $result))
    $result[$key]=$value;
}
USER249
  • 1,080
  • 7
  • 14
18

The only thing which worked for me is:

$array = array_unique($array, SORT_REGULAR);

Edit : SORT_REGULAR keeps the same order of the original array.

DeyaEldeen
  • 10,847
  • 10
  • 42
  • 75
iniravpatel
  • 1,553
  • 16
  • 24
5

sometimes array_unique() is not the way, if you want get unique AND duplicated items...

$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

results on

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

array ( 0 => '', 1 => '', 2 => '', 3 => 'A1', ) /* $duplicated */
AgelessEssence
  • 6,395
  • 5
  • 33
  • 37
  • This answer uses N number of searches while looping -- not very efficient. This answer makes loose comparisons which means that it may not be safe for general/public use. [Proof](https://3v4l.org/lU8Tt) – mickmackusa May 20 '23 at 22:28
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);
pawan kumar
  • 111
  • 7
  • 1
    The quickest way to achieve this is to use the array_flip function built-in to PHP[1]. array_flip will swap the array values with their keys and since an array cannot have duplicate keys you will end up with a unique set of keys that correspond to the values of the original array. To retrieve these keys as values you can use the array_keys function to retrieve your unique values. Both array_flip and array_keys are worst-case O(n) functions while array_unique has a worst-case of O(n log(n)).[2] – pawan kumar Apr 10 '19 at 12:39
  • 2
    Please add some more explanation to your answer (not to the comment section!). How does the given code remove duplicate values from a **single** array? Why do you need two arrays for that? – Nico Haase Apr 10 '19 at 13:05
  • 1
    Welcome to StackOverflow! I see that you have added some explanation in the comments of your answer, it would be helpful if you add this information as part of your answer itself. – n4m31ess_c0d3r Apr 10 '19 at 13:08
  • 2
    Seems more reasonable to add that comment as an edit to already long-existing answer (https://stackoverflow.com/a/52591730/2109067). – ankhzet Apr 10 '19 at 13:38
  • You can use single array with duplicate elements. I had problem of getting values from two arrays into one then remove duplicates. – pawan kumar Apr 11 '19 at 15:21
  • Calling `array_flip()` is not stable/reliable for general use. Values that coalesce to the same string or integer value will be consolidated/lost despite not being identical. Also, since PHP4.3 (maybe earlier, I don't know), this solution will emit Warnings when values are not strings or integers. [Proof](https://3v4l.org/8qEgr) I do not endorse this answer because it contains no explanatory text and is unsafe to use in some scenarios – mickmackusa May 20 '23 at 21:43
4

We can easily use arrar_unique($array); to remove duplicate elements But the problem in this method is that the index of the elements are not in order, will cause problems if used somewhere else later.

Use

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

Or

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

The first flip , flips the key value pair thus combines the elements with similar key(that was originally the value).

2nd flip to revert all the key value pairs. Finally array_value() sets each value with key starting from 0.

Note: Not to be used in associative array with predefined key value pairs

  • Calling `array_flip()` is not stable/reliable for general use. Values that coalesce to the same string or integer value will be consolidated/lost despite not being identical. Also, since PHP4.3 (maybe earlier, I don't know), this solution will emit Warnings when values are not strings or integers. [Proof](https://3v4l.org/FbHbs) The advice to use `array_unique()` was provided a decade earlier on this page. I do not recommend this answer -- it either gives redundant or unstable advice. – mickmackusa May 20 '23 at 21:38
3

We can create such type of array to use this last value will be updated into column or key value and we will get unique value from the array...

$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);
harsh kumar
  • 165
  • 7
  • Using values as keys is not stable when values are mutated by PHP upon being used as keys. This answer may not be suitable for public/general use. – mickmackusa May 20 '23 at 22:32
2

Depending on the size of your array, I have found

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

can be faster than array_unique.

Pang
  • 9,564
  • 146
  • 81
  • 122
Bollis
  • 385
  • 1
  • 11
  • Any more information on what's going on here and would it be faster with a bigger or smaller array. – Fi Horan Aug 31 '16 at 10:49
  • The double flip is going to remove duplicated values, because a key can't exist twice, otherwise it gets overwritten. If any value is duplicated and the array is flipped, the last occurrence (I assume) will be the value for the key. – Goldentoa11 Jan 18 '17 at 13:42
  • In PHP 7 I've noticed flipping a multidimensional array more than once may reorder array elements unexpectedly. – vhs May 31 '17 at 02:32
  • Calling `array_flip()` is not stable/reliable for general use. Values that coalesce to the same string or integer value will be consolidated/lost despite not being identical. Also, since PHP4.3 (maybe earlier, I don't know), this solution will emit Warnings when values are not strings or integers. [Proof](https://3v4l.org/FbHbs) – mickmackusa May 20 '23 at 22:31
2

If your concern is performance and you have a simple array, use:

array_keys(array_flip($array));

It's many times faster than array_unique.

TylerH
  • 20,799
  • 66
  • 75
  • 101
michal.jakubeczy
  • 8,221
  • 1
  • 59
  • 63
  • While it may be faster, it is also vulnerable to breakage because if non-string or non-integer values are used as keys, there may be unwanted collisions based on what PHP will use as the new keys. – mickmackusa May 20 '23 at 22:34
2

This example is just an alternative.

    <?php
    $numbers = [1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,65776567567,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1];
    $unique_numbers = [];
    
    foreach($numbers as $number)
    {
      if(!in_array($number,$unique_numbers)){
          $unique_numbers[] = $number;
      }
    }
    print(json_encode($unique_numbers)); //// Array is now 1,3,4,5,6,2,7, ....
Pathros
  • 10,042
  • 20
  • 90
  • 156
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 04 '22 at 00:36
  • https://stackoverflow.com/a/53607799/2943403 already demonstrated the use of `!in_array()` years earlier. `in_array()` is performing loose comparisons in this snippet and may not be fit for general/public use. – mickmackusa May 20 '23 at 22:36
1

explode(",", implode(",", array_unique(explode(",", $YOUR_ARRAY))));

This will take care of key associations and serialize the keys for the resulting new array :-)

apaderno
  • 28,547
  • 16
  • 75
  • 90
Deb
  • 1,918
  • 1
  • 18
  • 18
1

Remove duplicate values from an associative array in PHP.

$arrDup = Array ('0' => 'aaa-aaa' , 'SKU' => 'aaa-aaa' , '1' => '12/1/1' , 'date' => '12/1/1' , '2' => '1.15' , 'cost' => '1.15' );

foreach($arrDup as $k =>  $v){
  if(!( isset ($hold[$v])))
      $hold[$v]=1;
  else
      unset($arrDup[$k]);
}

Array ( [0] => aaa-aaa [1] => 12/1/1 [2] => 1.15 )

  • Using values as keys makes this technique unreliable for general use. When non-string or non-integer values are used as keys, they will either be silently converted to a string/integer or PHP will emit a Warning. – mickmackusa May 20 '23 at 22:24
1

There can be multiple ways to do these, which are as follows

//first method
$filter = array_map("unserialize", array_unique(array_map("serialize", $arr)));

//second method
$array = array_unique($arr, SORT_REGULAR);
Shahrukh Anwar
  • 2,544
  • 1
  • 24
  • 24
  • It might be worth mentioning that this unexplained answer is intended for multidimensional arrays and loops over the input array several times to do its job. `array_unique()` with `SORT_REGULAR` cannot be trusted with empty strings, `false` and `null` values -- [Proof](https://3v4l.org/qmqDI) – mickmackusa May 20 '23 at 21:46
0

That's a great way to do it. Might want to make sure its output is back an array again. Now you're only showing the last unique value.

Try this:

$arrDuplicate = array ("","",1,3,"",5);

foreach (array_unique($arrDuplicate) as $v){
  if($v != "") { $arrRemoved[] = $v; }
}
print_r ($arrRemoved);
Edson Medina
  • 9,862
  • 3
  • 40
  • 51
Dries B
  • 19
  • 3
  • Why did you bother to correct [the low-value answer](https://stackoverflow.com/a/8119319/2943403)? The question does not ask to populate an array of removed elements. Also there is no requirement to explicitly collect non-empty strings in a new array. The `array_unique()` advice has already been given. This answer adds no new, relevant advice to this page. – mickmackusa May 20 '23 at 22:22
0

try this short & sweet code -

$array = array (1,4,2,1,7,4,9,7,5,9);
$unique = array();

foreach($array as $v){
  isset($k[$v]) || ($k[$v]=1) && $unique[] = $v;
  }

var_dump($unique);

Output -

array(6) {
  [0]=>
  int(1)
  [1]=>
  int(4)
  [2]=>
  int(2)
  [3]=>
  int(7)
  [4]=>
  int(9)
  [5]=>
  int(5)
}
Rohit Suthar
  • 3,528
  • 1
  • 42
  • 48
  • 2
    Abusing boolean operators for control flow like this is needlessly confusing. Just use `if`. – Mark Amery Aug 27 '15 at 15:17
  • you are not getting making key but checking with key value – fahdshaykh Jul 03 '21 at 12:48
  • This solution is not fit for general use because when values are converted to string/integer keys some values are incorrectly deemed "the same". [Proof](https://3v4l.org/ZDcsU) – mickmackusa May 20 '23 at 22:16
0

It can be done through function I made three function duplicate returns the values which are duplicate in array.

Second function single return only those values which are single mean not repeated in array and third and full function return all values but not duplicated if any value is duplicated it convert it to single;

function duplicate($arr) {
    $duplicate;
    $count = array_count_values($arr);
    foreach($arr as $key => $value) {
        if ($count[$value] > 1) {
            $duplicate[$value] = $value;
        }
    }
    return $duplicate;
}
function single($arr) {
    $single;
    $count = array_count_values($arr);
    foreach($arr as $key => $value) {
        if ($count[$value] == 1) {
            $single[$value] = $value;
        }
    }
    return $single;
}
function full($arr, $arry) {
    $full = $arr + $arry;
    sort($full);
    return $full;
}
nyedidikeke
  • 6,899
  • 7
  • 44
  • 59
Mirza Obaid
  • 1,707
  • 3
  • 23
  • 35
  • Calling `array_count_values()` bears the same potential vulnerability as `array_flip()` -- problems can occur when values are converted to string/integer keys. – mickmackusa May 20 '23 at 21:59
0
<?php
$arr1 = [1,1,2,3,4,5,6,3,1,3,5,3,20];    
print_r(arr_unique($arr1));


function arr_unique($arr) {
  sort($arr);
  $curr = $arr[0];
  $uni_arr[] = $arr[0];
  for($i=0; $i<count($arr);$i++){
      if($curr != $arr[$i]) {
        $uni_arr[] = $arr[$i];
        $curr = $arr[$i];
      }
  }
  return $uni_arr;
}
sumityadavbadli
  • 251
  • 3
  • 5
  • Putting count($arr) in the loop is quite slow – Kiruahxh May 02 '18 at 08:18
  • 1
    I don't know that calling `count()` in the second parameter of the loop is _slow_, but it is certainly unnecessary because the count is never affected by the loop's body. This answer is not reliable for general use because loose comparisons result in unintended (non-unique) value eliminations. [Proof](https://3v4l.org/kdRZQ) (This answer is also missing its educational explanation. – mickmackusa May 20 '23 at 22:08
0
    if (@!in_array($classified->category,$arr)){        
                                    $arr[] = $classified->category;
                                 ?>

            <?php } endwhile; wp_reset_query(); ?>

first time check value in array and found same value ignore it

  • This answer does not run, is poorly formatted, should not endorse error suppression, is performing loose comparisons, and is missing its educational explanation. – mickmackusa May 20 '23 at 22:26
0

Here I've created a second empty array and used for loop with the first array which is having duplicates. It will run as many time as the count of the first array. Then compared with the position of the array with the first array and matched that it has this item already or not by using in_array. If not then it'll add that item to second array with array_push.

$a = array(1,2,3,1,3,4,5);
$count = count($a);
$b = [];
for($i=0; $i<$count; $i++){
    if(!in_array($a[$i], $b)){
        array_push($b, $a[$i]);
    }
}
print_r ($b);
  • Can you share some explanation about that code? For example, why don't you use a `foreach` loop? – Nico Haase Dec 04 '18 at 09:01
  • This is a sort form of doing and why I didn't use `foreach` because I'm much comfortable with for loop. That's it. – Aladin Banwal Dec 05 '18 at 02:26
  • Nevertheless, you should share some explanation with the code. Posting such answers on SO is not a good style: people with the same problem as the OP could come along, and they should be able to understand how your code solves the problem such that they can learn from it and adopt it to their needs – Nico Haase Dec 05 '18 at 06:37
  • `in_array()` in this example does not have its `strict` parameter set to `true`, so there may be some loose comparisons that trigger incorrect value eliminations in real projects. `in_array()` is probably one of PHP's slowest ways to search an array. – mickmackusa May 20 '23 at 22:02
0

As an alternative of array_unique() you may use php Set class

$array = array(1, 2, 2, 3);
$array = (new \Ds\Set($array))->toArray() ; // Array is now (1, 2, 3)
  • I assume there is a greater cost to instantiate a class and call one of its methods versus merely calling a native function. – mickmackusa May 20 '23 at 21:58