137

I am working with a one dimensional array in PHP. I would like to detect the presence of duplicate values, then count the number of duplicate values and output the results. For example, given the following array:

$array = [
    'apple',
    'orange',
    'pear',
    'banana',
    'apple',
    'pear',
    'kiwi',
    'kiwi',
    'kiwi'
];

I would like to print:

apple (2)
orange
pear (2)
banana
kiwi (3)

Any advice on how to approach this problem?

15 Answers 15

266

You can use array_count_values function

$array = array('apple', 'orange', 'pear', 'banana', 'apple',
'pear', 'kiwi', 'kiwi', 'kiwi');

print_r(array_count_values($array));

will output

Array
(
   [apple] => 2
   [orange] => 1
   [pear] => 2
   etc...
)
Sign up to request clarification or add additional context in comments.

1 Comment

This solution does not cover any non-integer and non-string values and in conclusion it produces sideffects.
131
if(count(array_unique($array))<count($array))
{
    // Array has duplicates
}
else
{
    // Array does not have duplicates
}

2 Comments

"...then count the number of duplicate values and out put the results."
This solution does not cover any non-integer and non-string values and in conclusion it produces sideffects. Using array_unique($array, SORT_REGULAR) forces PHP to check elements normally without changing the type, but it's a loose comparison. So different instances of one class with same content will be uniquified.
47
function array_not_unique( $a = array() )
{
    return array_diff_key( $a , array_unique( $a ) );
}

Result: (Demo)

array (
  4 => 'apple',
  5 => 'pear',
  7 => 'kiwi',
  8 => 'kiwi',
)

2 Comments

This is the only answer that returns only the duplicate values.
Extended to only give list of duplicate values (what I needed): return array_values(array_unique(array_diff_key($a, array_unique($a))));
9

You could try turning that array into a associative array with the fruits as keys and the number of occurrences as values. Bit long-winded, but it looks like:

$array = array('apple', 'orange', 'pear', 'banana', 'apple',
   'pear', 'kiwi', 'kiwi', 'kiwi');
$new_array = array();
foreach ($array as $key => $value) {
    if(isset($new_array[$value]))
        $new_array[$value] += 1;
    else
        $new_array[$value] = 1;
}
foreach ($new_array as $fruit => $n) {
    echo $fruit;
    if($n > 1)
        echo "($n)";
    echo "<br />";
}

1 Comment

Good answer, but PHP has an existing function that does just that: array_count_values
9

To get rid use array_unique(). To detect if have any use count(array_unique()) and compare to count($array).

Comments

2

Perhaps something like this (untested code but should give you an idea)?

$new = array();

foreach ($array as $value)
{
    if (isset($new[$value]))
        $new[$value]++;
    else
        $new[$value] = 1;
}

Then you'll get a new array with the values as keys and their value is the number of times they existed in the original array.

1 Comment

Good answer, but PHP has an existing function that does just that: array_count_values
1

Stuff them into a map (pseudocode)

map[string -> int] $m
foreach($word in $array)
{
    if(!$m.contains($word))
        $m[$word] = 0;

    $m[$word] += 1;
}

Comments

1

I didn't find the answer I was looking for, so I wrote this function. This will make an array that contains only the duplicates between the two arrays, but not print the number of times an element is duplicated, so it's not directly answering the question, but I'm hoping it'll help someone in my situation.

function findDuplicates($array1,$array2)
{
    $combined = array_merge($array1,$array2);
    $counted = array_count_values($combined);
    $dupes = [];
    $keys = array_keys($counted);
    foreach ($keys as $key)
    {   
        if ($counted[$key] > 1)
        {$dupes[] = $key;}
    }
    sort($dupes);
    return $dupes;
}
$array1 = [1,2,3,4,5];
$array2 = [4,5,6,7,8];
$dupes = findDuplicates($array1,$array2);
print_r($dupes);

Outputs:

Array
(
    [0] => 4
    [1] => 5
)

Comments

1
$data = ['outer', 'inner', 'sole', 'sole', 'outer', 'outer'];

$result = max(array_count_values($data));

if($result > 1) {
  echo 'Duplicate items were found!';
}

I think this way is shorter and cleaner.

1 Comment

This unexplained answer is ignoring the asker's requirements.
1
function array_not_unique(array $array): array
    {
        $duplicate_array = array_diff_key( $array , array_unique( $array ) );
        $unique_array = [];
        foreach ($array as $key => $value) {
            if ( in_array($value, $duplicate_array)) {
                $duplicate_array[$key] = $value;
            }
            else {
                $unique_array[$key] = $value;
            } 

        }

        return ["unique_array" => $unique_array, "duplicate_array" => $duplicate_array];
    }

Comments

1

This function give you the redundant values only

function array_find_redundant($A){
    $U=$N=[];
    foreach($A As $k=>$v){
        if(in_array($v,$U)){$N[$k]=$v;}else{$U[]=$v;}
    }
    return $N;
}

$A = ['A','B','B','C','C','C'];
$B = array_find_redundant($A); // [2=>'B',4=>'C',5=>'C'] 

Comments

1
$arr = [1,2,2,2,4,5,5,5,8,9,10,2,5,9,10,10];
array_count_values($arr); 
// OUT PUT Array(
//    2 => 4
//    5 => 4
//    9 => 2
//   10 => 3
// )

// If you want unique items
$items = array_keys( array_intersect( array_count_values($arr), [1] ) )

//If you want duplicate items 
$duplicates = array_keys( array_diff( array_count_values($arr), [1] ) )

Comments

0
$count = 0;
$output ='';
$ischeckedvalueArray = array();
for ($i=0; $i < sizeof($array); $i++) {
    $eachArrayValue = $array[$i];
    if(! in_array($eachArrayValue, $ischeckedvalueArray)) {
        for( $j=$i; $j < sizeof($array); $j++) {
            if ($array[$j] === $eachArrayValue) {
                $count++;
            }
        }
        $ischeckedvalueArray[] = $eachArrayValue;
        $output .= $eachArrayValue. " Repated ". $count."<br/>";
        $count = 0;
    }

}

echo $output;

Comments

0

Loop over the keys and values returned by array_count_values() and conditionally print the number of occurrences if greater than one.

Code: (Demo)

foreach (array_count_values($array) as $value => $count) {
    printf("%s%s\n", $value, $count > 1 ? " ($count)" :'');
}

Comments

-1

A simple method:

$array = array_values(array_unique($array, SORT_REGULAR));

1 Comment

This does not count non-unique values but just filters them.

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.