Löschen von doppelten Einträgen im multidimensionalen Array in PHP

Mit array_unique() bietet PHP eine Funktion an, um doppelte Einträge aus einem Array zu entfernen. Jedoch funktioniert diese Funktion nicht bei multidimensionalen Arrays. Zu Erläuterung, wie man trotzdem die doppelten Einträge aus solchen Arrays entfernt, dient das folgende Array als Beispiel.

$array = array(
	'0' => array(
		'0' => 'abc',
		'1' => 'def'
	),
	'1' => array(
		'0' => 'ghi',
		'1' => 'jkl'
	),
	'2' => array(
		'0' => 'abc',
		'1' => 'def'
	),
	'3' => array(
		'0' => 'mno',
		'1' => 'pqr'
	)
);

Leider bietet PHP nativ keine andere Funktion an, welche die doppelten Einträge abc und def des dritten Elements aus dem Array entfernt. Jedoch schafft die Kombination verschiedener Funktionen für dieses Problem Abhilfe. Nachfolgend wird für $array die Vorgehensweise erläutert.

  1. Mit array_map() wird auf jedes Element eines Arrays eine Callback-Funktion angewendet. Am Ende erhält man das Array mit den Elementen, nachdem diese Funktion darauf ausgeführt wurde. Als Callback-Funktion eignet sich serialize(). Durch die Anweisung array_map(‘serialize’, $array) wird aus dem oberen Array folgendes:
    array(4) {
    	[0] => string(34) "a:2:{i:0;s:3:"abc";i:1;s:3:"def";}"
    	[1] => string(34) "a:2:{i:0;s:3:"ghi";i:1;s:3:"jkl";}"
    	[2] => string(34) "a:2:{i:0;s:3:"abc";i:1;s:3:"def";}"
    	[3] => string(34) "a:2:{i:0;s:3:"mno";i:1;s:3:"pqr";}"
    }
  2. Das Array ist nun eindimensional. Somit lässt sich darauf array_unique($serializedArray) anwenden, womit doppelte Einträge entfernt werden. Das Ergebnis lautet:
    array(3) {
    	[0] => string(34) "a:2:{i:0;s:3:"abc";i:1;s:3:"def";}"
    	[1] => string(34) "a:2:{i:0;s:3:"ghi";i:1;s:3:"jkl";}"
    	[3] => string(34) "a:2:{i:0;s:3:"mno";i:1;s:3:"pqr";}"
    }
  3. Das Ausgangs-Array enthält die Schlüssel 0, 1, 2 und 3. Das bis hier modifizierte Array besitzt nicht mehr den Schlüssel 2. Letztlich wird also das Ausgangs-Array ohne serialisierte Schreibweise der Werte und ohne den zweiten Schlüssel benötigt. Hierfür eignet sich array_intersect_key($array, $serializedUniqueArray);, da lediglich die Schlüssel der beiden Arrays verglichen und nur die Werte von $array übernommen werden. Nach Anwendung von array_intersect_key() liegt folgendes Resultat vor:
    array(3) {
    	[0] => array(2) {
    		[0] => string(3) "abc"
    		[1] => string(3) "def"
    	}
    	[1] => array(2) {
    		[0] => string(3) "ghi"
    		[1] => string(3) "jkl"
    	}
    	[3] => array(2) {
    		[0] => string(3) "mno"
    		[1] => string(3) "pqr"
    	}
    }

Es gibt auch die Möglichkeit als letztes, statt array_intersect_key() noch einmal array_map() mit der Callback-Funktion unserialize() zu verwenden, um nach dem Aufruf von array_unique(), das Array wieder in die normale Struktur umzuwandeln. Bei so einem kleinen Array, wie in diesem Beispiel ist die Wahl der Methode aus Performance-Gründen noch nicht relevant. Jedoch wird mit der Größe des Arrays, die erneute Anwendung von array_map() zusehends langsamer laufen, als mit array_intersect_key(). Deshalb empfehle ich abschließend die 3 oben aufgeführten Punkte in folgendem Einzeiler zusammenzufassen:

$noDuplicates = array_intersect_key($array, array_unique(array_map('serialize', $array)));


Kommentar hinterlassen

Ihre eMail-Adresse wird nicht veröffentlicht.

Sie können folgende HTML-Tags und -Attribute verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>