Pregunta

Tengo una matriz

Array(
[0] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )

[1] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )

[2] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 8
        [frame_id] => 8
    )

[3] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )

[4] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )

)

Como se puede ver la clave de 0 es igual a 1, 3 y 4.Y la clave 2 es diferente de todos ellos.

Cuando se ejecuta el array_unique función de ellos, lo único que nos queda es

Array (
[0] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )
)

Alguna idea de por qué array_unique no funciona como se espera?

¿Fue útil?

Solución

Es porque array_unique compara elementos mediante una comparación de cadenas. Desde el docs :

  

Nota: Se consideran dos elementos   iguales si y sólo si (string) $ elem1   === (string) $ elem2. En otras palabras: cuando la representación de cadena es el mismo.   Se utilizará el primer elemento.

La representación de cadena de una matriz es simplemente la palabra Array, no importa lo que sus contenidos son.

Se puede hacer lo que quiere hacer utilizando la siguiente:

$arr = array(
    array('user_id' => 33, 'frame_id' => 3),
    array('user_id' => 33, 'frame_id' => 3),
    array('user_id' => 33, 'frame_id' => 8)
);

$arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr)));

//result:
array
  0 => 
    array
      'user_id' => int 33
      'user' => int 3
  2 => 
    array
      'user_id' => int 33
      'user' => int 8

Así es como funciona:

  1. Cada elemento de la matriz se serializa. Esta será único basado en la década de matriz contenido.

  2. Los resultados de este se ejecutan a través array_unique, por lo que sólo matrices con un único firmas se dejan.

  3. array_intersect_key tomará las llaves de los artículos únicos de la función de mapa / única (ya que las claves de la matriz fuente se conservan) y el tirón fuera de su fuente original array.

Otros consejos

array_unique() sólo es compatible con matrices multidimensionales en PHP 5.2.9 y superior.

En su lugar, puede crear un hash de la matriz y compruebe que no única-dad.

$hashes = array(); 

foreach($array as $val) { 
    $hashes[md5(serialize($val))] = $val; 
} 

array_unique($hashes);

Esta es una versión mejorada del @ ryeguy de respuesta :

<?php

$arr = array(
    array('user_id' => 33, 'tmp_id' => 3),
    array('user_id' => 33, 'tmp_id' => 4),
    array('user_id' => 33, 'tmp_id' => 5)
);


# $arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr)));
$arr = array_intersect_key($arr, array_unique(array_map(function ($el) {
    return $el['user_id'];
}, $arr)));

//result:
array
  0 => 
    array
      'user_id' => int 33
      'tmp_id' => int 3

En primer lugar, no hace innecesaria la serialización. En segundo lugar, a veces los atributos pueden ser diferentes, aun así la identificación es la misma.

Me he encontrado con Google Places API . Estaba combinar los resultados de varias solicitudes con diferentes tipos de objetos (piensa etiquetas). Pero tengo duplicados, ya que un objeto puede ser puesto en varias categorías (tipos). Y el método con serialize no funcionó, ya que los attrs eran diferentes, a saber, photo_reference y reference. Probablemente estos son como las identificaciones temporales.

array_unique recursiva trabajo deosn't, por lo que sólo piensa "Estos son todos Arrays, vamos a matar a todos menos uno ... aquí vamos!"

Respuesta rápida (TL;DR)

  • Valores distintos que puede ser extraído de la Matriz de PHP de AssociativeArrays usando foreach
  • Este es un enfoque simplista

Respuesta Detallada

Contexto

  • PHP 5.3
  • Array de PHP de AssociativeArrays (tabluar de datos compuesto variable)
  • Nombre alternativo para este compuesto variable es ArrayOfDictionary (AOD)

Problema

  • Escenario: DeveloperMarsher tiene un PHP tabular compuesto variable
    • DeveloperMarsher deseos para extraer valores distintos en un determinado par nombre-valor
    • En el ejemplo de abajo, DeveloperMarsher desea obtener filas para cada uno de los distintos fname par nombre-valor

Solución

  • example01 ;;DeveloperMarsher comienza con un tabluar variable de datos que se parece a esto

    $aodtable = json_decode('[
    {
      "fname": "homer"
      ,"lname": "simpson"
    },
    {
      "fname": "homer"
      ,"lname": "jackson"
    },
    {
      "fname": "homer"
      ,"lname": "johnson"
    },
    {
      "fname": "bart"
      ,"lname": "johnson"
    },
    {
      "fname": "bart"
      ,"lname": "jackson"
    },
    {
      "fname": "bart"
      ,"lname": "simpson"
    },
    {
      "fname": "fred"
      ,"lname": "flintstone"
    }
    ]',true);
    
  • example01 ;;DeveloperMarsher puede extraer valores distintos con un bucle foreach que las pistas visto valores

    $sgfield  =   'fname';
    $bgnocase =   true;
    
    //
    $targfield  =   $sgfield;
    $ddseen     =   Array();
    $vout       =   Array();
    foreach ($aodtable as $datarow) {
    if( (boolean) $bgnocase == true ){ @$datarow[$targfield] = @strtolower($datarow[$targfield]); }
    if( (string) @$ddseen[ $datarow[$targfield] ] == '' ){
      $rowout   = array_intersect_key($datarow, array_flip(array_keys($datarow)));
      $ddseen[ $datarow[$targfield] ] = $datarow[$targfield];
      $vout[] = Array( $rowout );
    }
    }
    //;;
    
    print var_export( $vout, true );
    

Resultado de salida

array (
  0 =>
  array (
    0 =>
    array (
      'fname' => 'homer',
      'lname' => 'simpson',
    ),
  ),
  1 =>
  array (
    0 =>
    array (
      'fname' => 'bart',
      'lname' => 'johnson',
    ),
  ),
  2 =>
  array (
    0 =>
    array (
      'fname' => 'fred',
      'lname' => 'flintstone',
    ),
  ),
)

Trampas

  • Esta solución no agregado en campos que no son parte de las DISTINTAS operación
  • Arbitraria pares de nombre-valor devuelto desde elegido de forma arbitraria filas distintas
  • Arbitraria orden de salida
  • Arbitrario manejo de carta-caso (es capital de Una distinta de la de menor caso ?)

Ver también

  • php array_intersect_key
  • php array_flip
function array_unique_recursive($array)
{
    $array = array_unique($array, SORT_REGULAR);

    foreach ($array as $key => $elem) {
        if (is_array($elem)) {
            $array[$key] = array_unique_recursive($elem);
        }
    }

    return $array;
}

No que hacer el truco?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top