¿Cómo detectar valores duplicados en la matriz PHP?

115

Estoy trabajando con una matriz unidimensional en PHP. Me gustaría detectar la presencia de valores duplicados, luego contar el número de valores duplicados y sacar los resultados. Por ejemplo, dada la siguiente matriz:

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

Me gustaría imprimir:

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

¿Algún consejo sobre cómo abordar este problema?

Gracias.

Miguel

mikey_w
fuente

Respuestas:

239

Puede usar la función array_count_values

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

print_r(array_count_values($array));

saldrá

Array
(
   [apple] => 2
   [orange] => 1
   [pear] => 2
   etc...
)
Silfverstrom
fuente
1
Esta solución no cubre ningún valor no entero ni de cadena y, en conclusión, produce efectos secundarios.
codekandis
110
if(count(array_unique($array))<count($array))
{
    // Array has duplicates
}
else
{
    // Array does not have duplicates
}
Ritvick Paliwal
fuente
"... luego cuente el número de valores duplicados y publique los resultados".
showdev
Esta solución no cubre ningún valor no entero ni de cadena y, en conclusión, produce efectos secundarios. El uso array_unique($array, SORT_REGULAR)obliga a PHP a verificar los elementos normalmente sin cambiar el tipo, pero es una comparación imprecisa. Por lo tanto, las diferentes instancias de una clase con el mismo contenido serán unificadas.
codekandis
38
function array_not_unique( $a = array() )
{
  return array_diff_key( $a , array_unique( $a ) );
}
Anton Maryanov
fuente
1
Esta es la única respuesta que devuelve solo los valores duplicados.
Redzarf
1
Extendido para dar solo una lista de valores duplicados (lo que necesitaba):return array_values(array_unique(array_diff_key($a, array_unique($a))));
Autumn Leonard
9

Puede intentar convertir esa matriz en una matriz asociativa con las frutas como claves y el número de ocurrencias como valores. Un poco prolijo, pero 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
fuente
1
Buena respuesta, pero PHP tiene una función existente que hace precisamente eso: array_count_values
Navarr
9

Para deshacerse del uso array_unique(). Para detectar si tiene algún uso count(array_unique())y compararlo count($array).

aksu
fuente
2

Guárdelos en un map(pseudocódigo)

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

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

¿Quizás algo como esto (código no probado pero debería darte una idea)?

$new = array();

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

Luego, obtendrá una nueva matriz con los valores como claves y su valor es la cantidad de veces que existieron en la matriz original.


fuente
Buena respuesta, pero PHP tiene una función existente que hace precisamente eso: 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
fuente
0

No encontré la respuesta que estaba buscando, así que escribí esta función. Esto creará una matriz que contiene solo los duplicados entre las dos matrices, pero no imprime la cantidad de veces que se duplica un elemento, por lo que no responde directamente a la pregunta, pero espero que ayude a alguien en mi situación.

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

Salidas:

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

Un método sencillo:

$array = array_values(array_unique($array, SORT_REGULAR));
la vida
fuente
Esto no cuenta los valores no únicos, solo los filtra.
m02ph3u5