Como detectar valores duplicados no array PHP?

115

Estou trabalhando com uma matriz unidimensional em PHP. Gostaria de detectar a presença de valores duplicados, contar o número de valores duplicados e enviar os resultados. Por exemplo, dada a seguinte matriz:

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

Eu gostaria de imprimir:

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

Algum conselho sobre como abordar este problema?

Obrigado.

Mike

mikey_w
fonte

Respostas:

239

Você pode usar a função array_count_values

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

print_r(array_count_values($array));

irá produzir

Array
(
   [apple] => 2
   [orange] => 1
   [pear] => 2
   etc...
)
Silfverstrom
fonte
1
Esta solução não cobre nenhum valor não inteiro e não string e, em conclusão, produz efeitos colaterais.
codekandis
110
if(count(array_unique($array))<count($array))
{
    // Array has duplicates
}
else
{
    // Array does not have duplicates
}
Ritvick Paliwal
fonte
"... então conte o número de valores duplicados e envie os resultados."
showdev
Esta solução não cobre nenhum valor não inteiro e não string e, em conclusão, produz efeitos colaterais. Usar array_unique($array, SORT_REGULAR)força o PHP a verificar os elementos normalmente sem alterar o tipo, mas é uma comparação vaga. Assim, diferentes instâncias de uma classe com o mesmo conteúdo serão exclusivas.
codekandis
38
function array_not_unique( $a = array() )
{
  return array_diff_key( $a , array_unique( $a ) );
}
Anton Maryanov
fonte
1
Esta é a única resposta que retorna apenas os valores duplicados.
Redzarf
1
Estendido para fornecer apenas uma lista de valores duplicados (o que eu precisava):return array_values(array_unique(array_diff_key($a, array_unique($a))));
Autumn Leonard
9

Você pode tentar transformar esse array em um array associativo com as frutas como chaves e o número de ocorrências como valores. Um pouco prolixo, mas parece:

$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 />";
}
Simon Scarfe
fonte
1
Boa resposta, mas o PHP tem uma função existente que faz exatamente isso: array_count_values
Navarr
9

Para se livrar, use array_unique(). Para detectar se tem alguma utilidade count(array_unique())e comparar count($array).

Aksu
fonte
2

Coloque-os em um map(pseudocódigo)

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

    $m[$word] += 1;
}
Anton Gogolev
fonte
2

Talvez algo assim (código não testado, mas deve dar uma ideia)?

$new = array();

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

Em seguida, você obterá um novo array com os valores como chaves e seu valor é o número de vezes que existiram no array original.


fonte
Boa resposta, mas o PHP tem uma função existente que faz exatamente isso: array_count_values
Navarr
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;
uday
fonte
0

Não encontrei a resposta que procurava, por isso escrevi esta função. Isso criará um array que contém apenas as duplicatas entre os dois arrays, mas não imprimirá o número de vezes que um elemento é duplicado, portanto, não está respondendo diretamente à pergunta, mas espero que ajude alguém na minha situação.

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);

Saídas:

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

Um método simples:

$array = array_values(array_unique($array, SORT_REGULAR));
a vida
fonte
Isso não conta valores não exclusivos, apenas os filtra.
m02ph3u5