61

I would like to check if my array has any duplicates and return the duplicated values in an array. I want this to be as efficient as possible.

Example:

$array = array( 1, 2, 2, 4, 5 );
function return_dup($array); // should return 2

$array2 = array( 1, 2, 1, 2, 5 );
function return_dup($array2); // should return an array with 1,2

Also the initial array is always 5 positions long

11 Answers 11

121

this will be ~100 times faster than array_diff

$dups = array();
foreach(array_count_values($arr) as $val => $c)
    if($c > 1) $dups[] = $val;
Sign up to request clarification or add additional context in comments.

3 Comments

Did a very quick benckmark and for me your method is only only coming out twice as fast as JAL's array_diff method, not 100 times faster.
Pretty sure it does @peter
Note that array_count_values only accepts string and integer values, so if your input array might include other types of values, this is not a good option. But it does work for the example in the question where it looks like the situation is dependably just an array of integers.
50

You can get the difference of the original array and a copy without duplicates using array_unique and array_diff_assoc:

array_diff_assoc($arr, array_unique($arr))

1 Comment

in 2023 this is faster then array_count_values
10
function array_dup($ar){
   return array_unique(array_diff_assoc($ar,array_unique($ar)));
}

Should do the trick.

Comments

6

You can do like this:

function showDups($array)
{
  $array_temp = array();

   foreach($array as $val)
   {
     if (!in_array($val, $array_temp))
     {
       $array_temp[] = $val;
     }
     else
     {
       echo 'duplicate = ' . $val . '<br />';
     }
   }
}


$array = array(1,2,2,4,5);
showDups($array);

Output:

duplicate = 2

Comments

2

in addition to gumbo's answer:

function returndup($arr)
{
  return array_diff_key($arr, array_unique($arr));
}

Comments

2
function returndup($array) 
{
    $results = array();
    $duplicates = array();
    foreach ($array as $item) {
        if (in_array($item, $results)) {
            $duplicates[] = $item;
        }

        $results[] = $item;
    }

    return $duplicates;
}

3 Comments

Not what the OP asked. They said it should be able to return more than one value.
Now it returns an array of duplicates. In the first post there was no notice that is needs to return multiple duplicates, so don't blame me!
Actually, there was: "if array is array(1,2,1,2,5); it should return an array with 1,2"
1

I did some tests and indeed @user187291's variant is the fastest. But, it turns out that @Gumbo's and @faebser's alternative are almost as fast, @faebser's being just slightly faster than @Gumbo's and sometimes even fastest of all.

Here's the code I used

$array = array(1, "hello", 1, "world", "hello");
$times = 1000000;

$start = microtime(true);
for ($i = 0; $i < $times; $i++) {
    $dups = array();
    foreach(array_count_values($array) as $val => $c)
        if( $c > 1) $dups[] = $val;
}
$end = microtime(true);

echo 'variant 1 (user187291): ' . ($end - $start);
echo '<br><br><br>';

$start = microtime(true);
for ($i = 0; $i < $times; $i++)
    $dups = array_unique(array_diff_assoc($array, array_unique($array)));
$end = microtime(true);

echo 'variant 2 (JAL): ' . ($end - $start);
echo '<br><br><br>';

$start = microtime(true);
for ($i = 0; $i < $times; $i++)
    $dups = array_diff_assoc($array, array_unique($array));
$end = microtime(true);

echo 'variant 3 (Gumbo): ' . ($end - $start);
echo '<br><br><br>';

$start = microtime(true);
for ($i = 0; $i < $times; $i++)
    $dups = array_diff_key($array, array_unique($array));
$end = microtime(true);

echo 'variant 4 (faebser): ' . ($end - $start);
echo '<br><br><br>';

Comments

0

I have found another way to return duplicates in an array

function printRepeating($arr, $size) 
{ 
    $i; 
    $j; 
    for($i = 0; $i < $size; $i++) 
        for($j = $i + 1; $j < $size; $j++) 
            if($arr[$i] == $arr[$j]) 
                echo $arr[$i], " "; 
}  



printRepeating($array, sizeof($array,0);

Comments

0

If you need a solution that will work with an array of arrays (or any array values other than integers or strings) try this:

function return_dup( $arr ) {
    $dups = array();
    $temp = $arr;
    foreach ( $arr as $key => $item ) {
        unset( $temp[$key] );
        if ( in_array( $item, $temp ) ) {
            $dups[] = $item;
        }
    }
    return $dups;
}


$arr = array(
    array(
        0 => 'A',
        1 => 'B',
    ),
    array(
        0 => 'A',
        1 => 'B',
    ),
    array(
        0 => 'C',
        1 => 'D',
    ),
    array(
        0 => 'C',
        1 => 'D',
    ),
    array(
        0 => 'E',
        1 => 'F',
    ),
    array(
        0 => 'F',
        1 => 'E',
    ),
    array(
        0 => 'Y',
        1 => 'Z',
    ),
);

var_export( return_dup( $arr ) );
/*
array (
    0 => array (
        0 => 'A',
        1 => 'B',
    ),
    1 => array (
        0 => 'C',
        1 => 'D',
    ),
)
*/

Comments

0

As per your problem if you have duplicate values then you have to return those values. I write a function for this problem. If your array has duplicate values this function returns these values within the array otherwise it returns null values. Here is an example:

function containsDuplicate($array_values) {
    $duplicates_values = [];
    for($i = 0; $i < count($array_values); $i++){
        for ($j=$i+1; $j <count($array_values) ; $j++) { 
            if ($array_values[$i] == $array_values[$j]) {
                $duplicates_values[] =  $array_values[$i];
            }
        }
    
    }
    if(count($duplicates_values) > 0){
        return $duplicates_values;
    }
}

1 Comment

Too much time complexity. Other answers are more direct, more elegant. count() should not be called on every iteration. if(count($duplicates_values) > 0){ can be if ($duplicates_values) {, but then why would anyone want to write a function that has a conditional return.
-3

$duplicate_array = array();

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

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

      if($i != $j && $array[$i] == $array[$j]){

        if(!in_array($array[$j], $duplicate_array)){

          $duplicate_array[] = $array[$j];

        }

      }

    }    

  }

2 Comments

At O(n^3), that's definitely the slowest approach.
O(n^4) actually. in_array() method works like a loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.