Question

J'ai un tableau

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
    )

)

Comme vous pouvez le voir sur la touche 0 est le même que 1, 3 et 4. Et la clé 2 est différent de tous.

Lors de l'exécution de la fonction array_unique sur eux, la gauche est seulement

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

Toutes les idées pourquoi array_unique ne fonctionne pas comme prévu?

Était-ce utile?

La solution

Il est parce que array_unique compare éléments à l'aide d'une comparaison de chaînes. De la docs :

  

Note: Deux éléments sont considérés   égaux si et seulement si (string) $ elem1   === (string) $ elem2. En d'autres termes: lorsque la représentation de chaîne est le même.   Le premier élément sera utilisé.

La représentation de chaîne d'un tableau est simplement le mot Array, peu importe son contenu.

Vous pouvez faire ce que vous voulez faire en utilisant les éléments suivants:

$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

Voilà comment cela fonctionne:

  1. Chaque élément du tableau est sérialisé. Cette sera unique basé sur le tableau de contenu.

  2. Les résultats de ce sont gérés par array_unique, de sorte que des tableaux uniques avec signatures sont laissés.

  3. array_intersect_key prendra les clés des éléments uniques de la fonction de carte unique / (sont conservés depuis les clés du tableau source) et tirez les de votre source d'origine matrice.

Autres conseils

array_unique() ne supporte que les tableaux multidimensionnels en PHP 5.2.9 et supérieur.

Au lieu de cela, vous pouvez créer un hachage du tableau et vérifier pour-ness unique.

$hashes = array(); 

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

array_unique($hashes);

Voici une version améliorée de réponse @ ryeguy :

<?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

D'abord, il ne fait pas sérialisation inutile. En second lieu, les attributs parfois peut être différent même si id est le même.

J'ai rencontré avec API Google Places . Je panachage des résultats de plusieurs requêtes avec différents types d'objets (pensez balises). Mais je suis en double, car un objet peut être mis en plusieurs catégories (types). Et la méthode avec serialize ne fonctionnait pas, puisque les attrs étaient différents, à savoir, photo_reference et reference. Probablement ceux-ci sont comme ids temporaires.

array_unique ne fonctionne pas récursif, il pense juste « ce sont tous les Arrays, nous allons tuer tous mais ... on y va! »

Réponse rapide (TL; DR)

  • valeurs distinctes peuvent être extraites de tableau PHP de AssociativeArrays utilisant foreach
  • Ceci est une approche simpliste

Réponse détaillée

Contexte

  • PHP 5.3
  • Array PHP de AssociativeArrays (tabluar variable de données composite)
  • Autre nom pour cette variable composite est ArrayOfDictionary (AOD)

Problème

  • Scénario: DeveloperMarsher a une variable composite sous forme de tableau PHP
    • DeveloperMarsher souhaite extraire des valeurs distinctes sur une paire valeur de nom spécifique
    • Dans l'exemple ci-dessous, DeveloperMarsher souhaite obtenir des lignes pour chaque distincte paire valeur du nom de fname

Solution

  • example01 ;; DeveloperMarsher commence par une variable de données tabluar qui ressemble à ceci

    $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 peut extraire des valeurs distinctes avec une boucle foreach qui suit les valeurs vu

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

Résultat de sortie

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',
    ),
  ),
)

Pitfalls

  • Cette solution ne regroupe pas sur les champs qui ne font pas partie de l'opération DISTINCT
  • paires nom-valeur arbitraire sont retournés à partir des lignes distinctes choisies arbitrairement
  • ordre de tri arbitraire de la production
  • Gestion arbitraire de la lettre cas (majuscule est distinct de minuscules a?)

Voir aussi

  • 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;
}

Ne pas faire l'affaire?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top