2011-06-23 15 views
10

si mis matrices esObtener las claves para valores duplicados en una matriz

Array ([0] => 2011-06-21 [1] => 2011-06-22 [2] => 2011-06-22 [3] => 2011-06-23 [4] => 
2011-06-23 [5] => 2011-06-24 [6] => 2011-06-24 [7] => 2011-06-25 [8] => 2011-06-25 [9] 
=> 2011-06-26 [10] => 2011-06-26 [11] => 2011-06-27 [12] => 2011-06-27 [13] => 2011-06- 
28 [14] => 2011-06-29 [15] => 2011-06-29 [16] => 2011-06-30 [17] => 2011-06-30 [18] => 
2011-07-01 [19] => 2011-07-01 [20] => 2011-07-02 [21] => 2011-07-02 [22] => 2011-07-03 
[23] => 2011-07-03 [24] => 2011-07-04 [25] => 2011-07-04 [26] => 2011-07-05 [27] => 2011- 
07-05 [28] => 2011-07-06 [29] => 2011-07-06 [30] => 2011-07-07 [31] => 2011-07-07) 
  1. Ahora, ¿cómo puedo mostrar las claves con valores duplicados? por ej. Aquí la función NO debe regresar ([0], [13]) ya que no hay duplicados con los valores. .
  2. Cómo encontrar la clave para el valor, por ejemplo "2011-06-29" debe devolver [15], [16]

Respuesta

16
function get_keys_for_duplicate_values($my_arr, $clean = false) { 
    if ($clean) { 
     return array_unique($my_arr); 
    } 

    $dups = $new_arr = array(); 
    foreach ($my_arr as $key => $val) { 
     if (!isset($new_arr[$val])) { 
     $new_arr[$val] = $key; 
     } else { 
     if (isset($dups[$val])) { 
      $dups[$val][] = $key; 
     } else { 
      $dups[$val] = array($key); 
      // Comment out the previous line, and uncomment the following line to 
      // include the initial key in the dups array. 
      // $dups[$val] = array($new_arr[$val], $key); 
     } 
     } 
    } 
    return $dups; 
} 

, obviamente, el nombre de la función es un poco largo;)

Ahora $ dups contendrá una matriz multidimensional marcada por el valor duplicado, que contiene cada clave que fue un duplicado, y si envía "verdadero" como su segundo argumento, devolverá la matriz original sin los valores duplicados.

Alternativamente, usted podría pasar la matriz original como referencia y que ajustará en consecuencia, mientras que la devolución de su gama duplicado

+1

que podría acortar la ruta de código cuando '$ limpia === true' poniendo' if ($ limpia === true) {return array_unique ($ my_arr); } 'en la parte superior;) – Dereleased

+0

cierto que gracias :) – Trey

+0

Por cierto, el método más rápido que he probado hasta ahora, maneja 100 iteraciones de una matriz de más de 100.000 elementos en aproximadamente 0.04463 segundos por iteración! – Dereleased

1
$array = array(0 => "1", 1 => "1", 2 => "2", 3 => "3"); 
$count = array(); 
foreach($array as $key => $value) { 
    if(!isset($count[$value])) { 
    $count[$value] = 0; 
    } 
    $count[$value]++; 
} 


$result = array_filter($count, function($value) { 
    return $value > 1; 
}); 

$result = array_keys($result); 

var_dump($result); 

salida

array(1) { 
    [0]=> 
    int(1) 
} 
1

aquí es un código de tipo

$your_array = array(0 => '2011-06-21', 1 => '2011-06-22', 2 => '2011-06-22', 3 => '2011-06-23', 4 => 
'2011-06-23', 5 => '2011-06-24', 6 => '2011-06-24', 7 => '2011-06-25', 8 => '2011-06-25', 9 
=> '2011-06-26', 10 => '2011-06-26', 11 => '2011-06-27', 12 => '2011-06-27', 13 => '2011-06- 
28', 14 => '2011-06-29', 15 => '2011-06-29', 16 => '2011-06-30', 17 => '2011-06-30', 18 => 
'2011-07-01', 19 => '2011-07-01', 20 => '2011-07-02', 21 => '2011-07-02', 22 => '2011-07-03', 
23 => '2011-07-03', 24 => '2011-07-04', 25 => '2011-07-04', 26 => '2011-07-05', 27 => '2011- 
07-05', 28 => '2011-07-06', 29 => '2011-07-06', 30 => '2011-07-07', 31 => '2011-07-07'); 

$keys_of_duplicated = array(); 
$array_keys = array(); 

foreach($your_array as $key => $value) { 
    //- get the keys of the actual value 
    $array_keys = array_keys($your_array, $value); 

    //- if there is more then one key collected we register it 
    if(count($array_keys) > 1) { 
     //- foreach key that have the same value we check if i'ts already registered 
     foreach($array_keys as $key_registered) { 
      //- if not registered we register it 
      if(!in_array($key_registered, $keys_of_duplicated)) { 
       $keys_of_duplicated[] = $key_registered; 
      } 
     } 
    } 
} 

var_dump($keys_of_duplicated); 

$ keys_of_duplicated ahora es la matriz que contiene las claves de duplicado matrices;) bye

+1

En mi prueba, este tiempo de espera (60 segundos) en una matriz suficientemente grande (100.000 en mi prueba). – Dereleased

12

Voy a responder a la segunda pregunta primero. Desea usar array_keys con el "valor de búsqueda" especificado.

$keys = array_keys($array, "2011-06-29") 

En el siguiente ejemplo, $duplicates contendrá los valores de duplicación mientras $result contendrá los que no son duplicados. Para obtener las llaves, simplemente use array_keys.

<?php 

$array = array(
    'a', 
    'a', 
    'b', 
    'c', 
    'd' 
); 

// Unique values 
$unique = array_unique($array); 

// Duplicates 
$duplicates = array_diff_assoc($array, $unique); 

// Unique values 
$result = array_diff($unique, $duplicates); 

// Get the unique keys 
$unique_keys = array_keys($result); 

// Get duplicate keys 
$duplicate_keys = array_keys(array_intersect($array, $duplicates)); 

Resultado:

// $duplicates 
Array 
(
    [1] => a 
) 

// $result 
Array 
(
    [2] => b 
    [3] => c 
    [4] => d 
) 

// $unique_keys 
Array 
(
    [0] => 2 
    [1] => 3 
    [2] => 4 
) 

// $duplicate_keys 
Array 
(
    [0] => 0 
    [1] => 1 
) 
+0

Esto devolverá valores, no claves. – cypher

+0

@cypher - Tienes razón. Olvidé incluir 'array_keys'. He actualizado mi respuesta. –

+0

También, la pregunta interesante sería si quería imprimir todas las claves duplicadas, en su caso '0' y' 1' para 'a' – cypher

0
$array = array(
    '2011-06-21','2011-06-22','2011-06-22','2011-06-23', 
    '2011-06-23','2011-06-24','2011-06-24','2011-06-25', 
    '2011-06-25','2011-06-26','2011-06-26','2011-06-27', 
    '2011-06-27','2011-06-28','2011-06-29','2011-06-29', 
    '2011-06-30','2011-06-30','2011-07-01','2011-07-01', 
    '2011-07-02','2011-07-02','2011-07-03','2011-07-03', 
    '2011-07-04','2011-07-04','2011-07-05','2011-07-05', 
    '2011-07-06','2011-07-06','2011-07-07','2011-07-07', 
); 

function getDupKeys(array $array, $return_first = true, $return_by_key = true) { 
    $seen = array(); 
    $dups = array(); 

    foreach ($array as $k => $v) { 
     $vk = $return_by_key ? $v : 0; 
     if (!array_key_exists($v, $seen)) { 
      $seen[$v] = $k; 
      continue; 
     } 
     if ($return_first && !array_key_exists($v, $dups)) { 
      $dups[$vk][] = $seen[$v]; 
     } 
     $dups[$vk][] = $k; 
    } 
    return $return_by_key ? $dups : $dups[0]; 
} 

Si ambos parámetros opcionales son verdaderas, devuelve una matriz de matrices; la clave de cada matriz secundaria será el valor que no sea único, y los valores de la matriz serán todas aquellas claves que tengan ese valor.

Si el primer parámetro opcional es falso, solo las claves después de se devolverá la primera instancia de un valor no único (es decir, para la matriz dada, cada valor devuelve solo una clave, la segunda vez que ocurrió , en lugar de la primera).

Si el segundo parámetro es opcional, en lugar de devolver una matriz de matrices, devuelve una matriz plana que contiene todas las claves duplicadas (exactamente qué claves devuelve están dictadas por el parámetro opcional anterior).

Aquí está un print_r volcado, porque es más bonita:

print_r(getDupKeys($array)); 

Array 
(
    [2011-06-22] => Array 
     (
      [0] => 1 
      [1] => 2 
     ) 

    [2011-06-23] => Array 
     (
      [0] => 3 
      [1] => 4 
     ) 

    [2011-06-24] => Array 
     (
      [0] => 5 
      [1] => 6 
     ) 

    [2011-06-25] => Array 
     (
      [0] => 7 
      [1] => 8 
     ) 

    [2011-06-26] => Array 
     (
      [0] => 9 
      [1] => 10 
     ) 

    [2011-06-27] => Array 
     (
      [0] => 11 
      [1] => 12 
     ) 

    [2011-06-29] => Array 
     (
      [0] => 14 
      [1] => 15 
     ) 

    [2011-06-30] => Array 
     (
      [0] => 16 
      [1] => 17 
     ) 

    [2011-07-01] => Array 
     (
      [0] => 18 
      [1] => 19 
     ) 

    [2011-07-02] => Array 
     (
      [0] => 20 
      [1] => 21 
     ) 

    [2011-07-03] => Array 
     (
      [0] => 22 
      [1] => 23 
     ) 

    [2011-07-04] => Array 
     (
      [0] => 24 
      [1] => 25 
     ) 

    [2011-07-05] => Array 
     (
      [0] => 26 
      [1] => 27 
     ) 

    [2011-07-06] => Array 
     (
      [0] => 28 
      [1] => 29 
     ) 

    [2011-07-07] => Array 
     (
      [0] => 30 
      [1] => 31 
     ) 

) 

print_r(getDupKeys($array, false)); 

Array 
(
    [2011-06-22] => Array 
     (
      [0] => 2 
     ) 

    [2011-06-23] => Array 
     (
      [0] => 4 
     ) 

    [2011-06-24] => Array 
     (
      [0] => 6 
     ) 

    [2011-06-25] => Array 
     (
      [0] => 8 
     ) 

    [2011-06-26] => Array 
     (
      [0] => 10 
     ) 

    [2011-06-27] => Array 
     (
      [0] => 12 
     ) 

    [2011-06-29] => Array 
     (
      [0] => 15 
     ) 

    [2011-06-30] => Array 
     (
      [0] => 17 
     ) 

    [2011-07-01] => Array 
     (
      [0] => 19 
     ) 

    [2011-07-02] => Array 
     (
      [0] => 21 
     ) 

    [2011-07-03] => Array 
     (
      [0] => 23 
     ) 

    [2011-07-04] => Array 
     (
      [0] => 25 
     ) 

    [2011-07-05] => Array 
     (
      [0] => 27 
     ) 

    [2011-07-06] => Array 
     (
      [0] => 29 
     ) 

    [2011-07-07] => Array 
     (
      [0] => 31 
     ) 

) 

print_r(getDupKeys($array, true, false)); 

Array 
(
    [0] => 1 
    [1] => 2 
    [2] => 3 
    [3] => 4 
    [4] => 5 
    [5] => 6 
    [6] => 7 
    [7] => 8 
    [8] => 9 
    [9] => 10 
    [10] => 11 
    [11] => 12 
    [12] => 14 
    [13] => 15 
    [14] => 16 
    [15] => 17 
    [16] => 18 
    [17] => 19 
    [18] => 20 
    [19] => 21 
    [20] => 22 
    [21] => 23 
    [22] => 24 
    [23] => 25 
    [24] => 26 
    [25] => 27 
    [26] => 28 
    [27] => 29 
    [28] => 30 
    [29] => 31 
) 

print_r(getDupKeys($array, false, false)); 

Array 
(
    [0] => 2 
    [1] => 4 
    [2] => 6 
    [3] => 8 
    [4] => 10 
    [5] => 12 
    [6] => 15 
    [7] => 17 
    [8] => 19 
    [9] => 21 
    [10] => 23 
    [11] => 25 
    [12] => 27 
    [13] => 29 
    [14] => 31 
) 
0

I rea Como François responde, aquí hay algo que se me ocurre que conserva las llaves. Voy a responder a la primera pregunta primero:

$array = array('2011-06-21', '2011-06-22', '2011-06-22'); 
/** 
* flip an array like array_flip but 
* preserving multiple keys per an array value 
* 
* @param array $a 
* @return array 
*/ 
function array_flip_multiple(array $a) { 
    $result = array(); 
    foreach($a as $k=>$v) 
     $result[$v][]=$k 
     ; 
    return $result; 
} 

$hash = array_flip_multiple($array); 

// filter $hash based on your specs (2 or more) 
$hash = array_filter($hash, function($items) {return count($items) > 1;}); 

// get all remaining keys 
$keys = array_reduce($hash, 'array_merge', array()); 

var_dump($array, $hash, $keys); 

salida es:

# original array 
array(3) { 
    [0]=> 
    string(10) "2011-06-21" 
    [1]=> 
    string(10) "2011-06-22" 
    [2]=> 
    string(10) "2011-06-22" 
} 

# hash (filtered) 
array(1) { 
    ["2011-06-22"]=> 
    array(2) { 
    [0]=> 
    int(1) 
    [1]=> 
    int(2) 
    } 
} 

# the keys 
array(2) { 
    [0]=> 
    int(1) 
    [1]=> 
    int(2) 
} 

Así que ahora la segunda pregunta: ¿

sólo tiene que utilizar el $hash para obtener las claves para el valor:

var_dump($hash['2011-06-22']); devuelve las claves.

La ventaja es que, si necesita verificar múltiples valores, los datos ya están almacenados en el hash y están disponibles para su uso.

1

Tuve un problema similar al de la pregunta n. ° 1 del OP. Todo lo que necesitaba eran las claves para los valores duplicados en mi matriz original. Esto es lo que ocurrió:

$array = array('yellow', 'red', 'green', 'brown', 'red', 'brown'); 

$counts = array_count_values($array); 
$filtered = array_filter($counts, function($value) { 
    return $value != 1; 
}); 
$result = array_keys(array_intersect($array, array_keys($filtered))); 

Y para la salida:

print_r($result); 
Array 
(
    [0] => 1 
    [1] => 3 
    [2] => 4 
    [3] => 5 
) 
1
function getDuplicateValueKeys($my_arr, $clean = false) 
{ 
    if ($clean) { 
     return array_unique($my_arr); 
    } 
    $dups = array(); 
    $new_arr = array(); 
    $dup_vals = array(); 

    foreach ($my_arr as $key => $value) { 
     if (!isset($new_arr[$value])) { 
      $new_arr[$value] = $key; 
     } else { 
      array_push($dup_vals,$value); 
     } 
    } 

    foreach ($my_arr as $key => $value) { 
     if (in_array($value, $dup_vals)) { 
      if (!isset($dups[$value])) { 
       $dups[$value]=array($key); 
      }else{ 
       array_push($dups[$value],$key); 
      } 
     } 
    } 

    return $dups; 
} 
Cuestiones relacionadas