Führen Sie zwei Arrays zusammen, die Objekte enthalten, und entfernen Sie doppelte Werte

Lesezeit: 4 Minuten

Benutzer-Avatar
da ich bin

Ich muss zwei Arrays von Objekten zu einem Array zusammenführen und Duplikate entfernen email Werte.

Wie kann ich das machen?

Dies sind meine Beispiel-Arrays:

$array1 = [
    (object) ["email" => "gffggfg"],
    (object) ["email" => "[email protected]"],
    (object) ["email" => "wefewf"],
];
$array2 = [
    (object) ["email" => "[email protected]"],
    (object) ["email" => "wefwef"],
    (object) ["email" => "wefewf"],
];

Mein erwartetes Ergebnis ist:

[
   (object) ['email' => 'gffggfg'],
   (object) ['email' => '[email protected]'],
   (object) ['email' => 'wefewf'],
   (object) ['email' => '[email protected]'],
   (object) ['email' => 'wefwef'],
]

Benutzer-Avatar
Jeroen

Sie können die kombinieren array_merge() Funktion mit der array_unique() Funktion (beide Titel sind ziemlich selbsterklärend)

$array = array_unique (array_merge ($array1, $array2));

  • Nun, wie ich sehen kann, scheint array_merge() keine Duplikate zu berechnen, also ist array_unique() in meinem Fall veraltet oder nicht!?

    – da ich bin

    13. Mai 2012 um 14:44 Uhr

  • array_merge() fügt keine doppelten Schlüssel hinzu, aber wenn Sie doppelte Werte mit unterschiedlichen Schlüsseln haben, werden diese hinzugefügt

    – Jeroen

    13. Mai 2012 um 14:47 Uhr


  • Sollte SORT_REGULAR und andere Optionen erwähnen, um Fehler beim Konvertieren von Typen zu vermeiden.

    – Brandon Elliott

    31. Juli 2016 um 9:25 Uhr

  • Hinweis: array_unique behält Schlüssel bei, sodass Sie für numerisch indizierte Arrays, wenn Sie sequentielle Schlüssel benötigen, schnell neue Schlüssel erstellen können, indem Sie mit einem Aufruf von umbrechen array_values

    – Hochvolt

    30. November 2016 um 13:06 Uhr


  • Trotz der Flut an Upvotes und dem grünen Häkchen bei dieser knappen Antwort, es ist anhand der Beispieldaten des Fragestellers nachweislich falsch.

    – mickmackusa

    4. Juni um 6:52


Wenn ich die Frage richtig verstehe:

 $a1 = Array(1,2,3,4);
 $a2 = Array(4,5,6,7);
 $array =  array_diff(array_merge($a1,$a2),array_intersect($a1,$a2));
 print_r($array);

Rückkehr

Array
(
[0] => 1
[1] => 2
[2] => 3
[5] => 5
[6] => 6
[7] => 7
)

  • Entschuldigung, ich habe vergessen, dass ich ein mehrstufiges Array habe, kein einfaches Array

    – da ich bin

    13. Mai 2012 um 14:49 Uhr

  • Nicht nur diese unerklärliche Antwort nicht mit den Daten des Fragestellers arbeiten, selbst wenn dies der Fall wäre, wäre es nicht effizient, da es sich um wertbasierte Vergleiche handelt. In PHP werden schlüsselbasierte Vergleiche immer schneller ausgeführt.

    – mickmackusa

    4. Juni um 6:50 Uhr


Benutzer-Avatar
Jöri Noort

Ich habe einige Benchmarks aller Möglichkeiten durchgeführt, die ich mir vorstellen kann, dies zu tun. Ich habe Tests zum Stapeln vieler Arrays mit 10-20 String-Elementen durchgeführt, was zu einem Array mit allen eindeutigen Strings darin führte. Dies sollte ungefähr gleich sein, wenn nur 2 Arrays gestapelt werden.

Das schnellste, was ich gefunden habe, war das Einfachste, was ich versucht habe.

$uniques = [];
foreach($manyArrays as $arr ) {
  $uniques = array_unique(array_merge($uniques, $arr));
}

Ich hatte dies als “zu naiv zum Arbeiten” gebrandmarkt, da es das Uniques-Array bei jeder Iteration sortieren muss. Dies jedoch schneller als jede andere Methode. Testen mit 500.000 Elementen in ManyArrays, die jeweils 10-20 Strings von PHP 7.3 enthalten.

An zweiter Stelle folgt diese Methode, die etwa 10 % langsamer ist.

$uniques = [];
foreach($manyArrays as $arr ) {
  foreach($arr as $v) {
    if( !in_array($v, $uniques, false) ) {
      $uniques[] = $v;
    }
  }
}

Die zweite Methode könnte in manchen Fällen besser sein, da diese den „strengen“ Parameter von unterstützt in_array() für strenge Typprüfung. Wenn sie jedoch auf „true“ gesetzt ist, wird die zweite Option deutlich langsamer als die erste (ca. 40 %). Die erste Option unterstützt keine strikte Typprüfung.

  • Wie bevölkern Sie $manyArrays im Rahmen dieser Aufgabe?

    – mickmackusa

    4. Juni um 6:46

Schnellere Lösung:

function concatArrays($arrays){
    $buf = [];
    foreach($arrays as $arr){
        foreach($arr as $v){
            $buf[$v] = true;
        }
    }
    return array_keys($buf);
}


$array = concatArrays([$array1, $array2]);

Benutzer-Avatar
mickmackusa

Weil die email Eigenschaften im Array von Objekten nicht numerische Werte enthalten, können Sie vorübergehend Schlüssel der ersten Ebene zuweisen (mit array_column()) dann führen Sie die beiden Arrays mit dem Union-Operator zusammen (eine funktionslose Aktion).

Wenn die temporären Schlüssel Ihren nächsten Prozess stören, können Sie das Array mit neu indizieren array_values().

Code: (Demo)

var_export(
    array_values(
        array_column($array1, null, 'email')
        + array_column($array2, null, 'email')
    )
);

Ausgabe:

array (
  0 => 
  (object) array(
     'email' => 'gffggfg',
  ),
  1 => 
  (object) array(
     'email' => '[email protected]',
  ),
  2 => 
  (object) array(
     'email' => 'wefewf',
  ),
  3 => 
  (object) array(
     'email' => '[email protected]',
  ),
  4 => 
  (object) array(
     'email' => 'wefwef',
  ),
)

“Einzigartige Objekte zusammenführen und behalten” funktioniert auch mit einem speziellen Flag.

Code: (Demo)

var_export(
    array_unique(
        array_merge($array1, $array2),
        SORT_REGULAR
    )
);
// same result as other snippet

Benutzer-Avatar
Marek N

Eine etwas späte Antwort, aber ich habe gerade den Array-Union-Operator gefunden + macht den Job ziemlich gut (gefunden hier im 3. Abschnitt).

$array1 + $array2 = $array //if duplicate found, the value in $array1 will be considered ($array2 value for array_merge, if keys clearly specified)

1018760cookie-checkFühren Sie zwei Arrays zusammen, die Objekte enthalten, und entfernen Sie doppelte Werte

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy