Frage

Ich habe ein Array

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
    )

)

Wie Sie die Taste 0 sehen kann, ist die gleiche wie 1, 3 und 4. Und Taste 2 unterscheidet sich von allen.

Wenn ihnen die array_unique Funktion ausgeführt wird, die nur links

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

Irgendwelche Ideen, warum array_unique wird nicht wie erwartet funktioniert?

War es hilfreich?

Lösung

Es ist, weil array_unique Artikel vergleicht einen String-Vergleich verwenden. Von der docs :

  

Hinweis: Zwei Elemente werden als   gleich, wenn und nur wenn (string) $ elem1   === (string) $ elem2. In Worten: Wenn die String-Darstellung ist das gleiche.   Das erste Element verwendet werden.

Die Stringdarstellung eines Arrays ist einfach das Wort Array, egal was ihr Inhalt ist.

Sie können tun, was Sie mit dem folgenden tun:

$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

Hier ist, wie es funktioniert:

  1. Jedes Array-Element wird serialisiert. Dies wird auf der Grundlage der Arrays eindeutig sein Inhalt.

  2. Die Ergebnisse dieser durch array_unique laufen, so nur Arrays mit einzigartigen Unterschriften gelassen werden.

  3. array_intersect_key nehmen die Schlüssel der Unikate aus die Karte / einzigartige Funktion (da die Schlüssel des Quell-Arrays erhalten bleiben) und Pull sie aus Ihrer ursprünglichen Quelle Array.

Andere Tipps

array_unique() unterstützt nur mehrdimensionale Arrays in PHP 5.2.9 und höher.

Sie können stattdessen einen Hash-Wert des Array erstellen und überprüfen Sie es auf einzigartige-ness.

$hashes = array(); 

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

array_unique($hashes);

Hier ist eine verbesserte Version von @ ryeguy Antwort :

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

Als erstes ist es nicht unnötige Serialisierung tun. Zweitens manchmal Attribute sein können unterschiedlich sogar so id gleich ist.

Ich habe in sie laufen mit Google Places API . Ich war Ergebnisse mehrerer Anfragen mit verschiedenen Arten von Objekten (man denke Tags) zu kombinieren. Aber ich habe Duplikate, da ein Objekt in mehrere Gruppen unterteilt werden können (Typen). Und die Methode mit serialize funktionierte nicht, da die attrs verschieden waren, nämlich photo_reference und reference. Wahrscheinlich sind diese wie temporäre IDs.

array_unique deosn't Arbeit rekursiv, so dass es nur denkt „das alle Arrays sind, lassen Sie uns töten alle bis auf einen ... hier gehen wir!“

Schnelle Antwort (TL; DR)

  • Ausgeprägte Werte können von PHP Array von AssociativeArrays mit foreach
  • extrahiert werden
  • Dies ist ein vereinfachenden Ansatz

Detaillierte Antwort

Kontext

  • PHP 5.3
  • PHP Array von AssociativeArrays (tabluar zusammengesetzten Datenvariable)
  • Alternate Name für diese Verbund Variable ArrayOfDictionary (AOD)

Problem

  • Szenario: DeveloperMarsher hat eine PHP tabellarisch zusammengesetzter Variable
    • DeveloperMarsher wünscht unterschiedliche Werte auf einem bestimmten Namen-Wert-Paar extrahieren
    • Im Beispiel unten, DeveloperMarsher wünscht Zeilen für jedes einzelnes fname Name-Wert-Paar erhalten

Lösung

  • EXAMPLE01 ;; DeveloperMarsher beginnt mit einem tabluar Datenvariable, die wie folgt aussieht

    $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 können unterschiedliche Werte mit einer foreach Schleife extrahieren, die Spuren gesehen Werte

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

Ausgabeer

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

  • Diese Lösung funktioniert nicht Aggregat auf Felder, die nicht Teil der DISTINCT-Operation sind
  • beliebige Name-Wert-Paare werden aus willkürlich gewählten unterschiedlichen Zeilen zurück
  • Frei wählbare Sortierreihenfolge der Ausgabe
  • Willkürliche Umgang mit Brieftasche (ist Kapital A unterscheidet sich von Klein a?)

Siehe auch

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

nicht, dass der Trick?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top