Duplikate aus Arrays entfernen (Thema: PHP Beispiele)

Die verschiedenen Möglichkeiten zum Entfernen von Duplikaten aus Arrays, insbesondere unter Anwendung von array_unique()

URL: http://www.rither.de/a/informatik/php-beispiele/arrays/duplikate-aus-arrays-entfernen/

1. Grundlegende Anwendung von array_unique()


Zum Entfernen von mehrfach vorkommenden Werten aus einem Array (sodass jeder Wert nur noch ein Mal vorkommt, vergleichbar mit DISTINCT bei SQL) stellt PHP die Funktion array_unique($array) zur Verfügung.
PHP-Code
<?php
	$arr = array(1, 2, 4, 1, 6, 2, 9, 9, 10);
	$arr = array_unique($arr);
	foreach ($arr as $val) {
		echo("$val, ");
	}
?>
Ausgabe
1, 2, 4, 6, 9, 10, 

Zu beachten ist, dass array_unique() jeden Wert standardmäßig in einen String umwandelt, sodass z.B. (int)1 und (string)"1" als der selbe Wert betrachtet werden.
PHP-Code
<?php
	$arr = array(1, 4, 8, 'hallo', '1', 8, 'vier', '4');
	$arr = array_unique($arr);
	foreach ($arr as $val) {
		echo("$val, ");
	}
?>
Ausgabe
1, 4, 8, hallo, vier, 

array_unique() erhält die Schlüssel so weit wie möglich bei.
PHP-Code
<?php
	$arr = array('eins'=>1, 'zwei'=>2, 'noch_eine_eins'=>1);
	$arr = array_unique($arr);
	foreach ($arr as $key=>$val) {
		echo("$key=>$val, ");
	}
?>
Ausgabe
eins=>1, zwei=>2, 

Sofern das Array nur numerische Werte enthält, kann dieser Umstand der Funktion signalisiert werden, wodurch die Performance verbessert wird.
PHP-Code
<?php
	$arr = array(15, 19, 7, 15, 100, 101, 15, 19);
	$arr = array_unique($arr, SORT_NUMERIC);
	foreach ($arr as $val) {
		echo("$val, ");
	}
?>
Ausgabe
15, 19, 7, 100, 101, 


2. array_unique() bei verschiedener Groß- und Kleinschreibung


Enthält das Array Strings, dann agiert array_unique() standardmäßig case-sensitive.
"hallo" und "Hallo" würden daher zum Beispiel als unterschiedliche Werte angesehen.
Die nachfolgende Funktion verhält sich wie array_unique(), unterscheidet aber nicht zwischen Groß- und Kleinschreibung.
Werden mehrere Werte mit unterschiedlicher Groß- und Kleinschreibung gefunden, dann wird nur der erste dieser Werte übernommen.
PHP-Code
<?php
	function array_unique_ci($arr) {
		$out = array();
		$found = array();
		foreach ($arr as $key=>$val) {
			$l = mb_strtolower(strval($val));
			if (!isset($found[$l])) {
				$out[$key] = $val;
			}
			$found[$l] = true;
		}
		return $out;
	}

	$arr = array('eins', 'ZwEi', 'DREI', 'drei', 'einS', 'zwei', 1, 3.141);
	$arr = array_unique_ci($arr);
	foreach ($arr as $val) {
		echo("$val, ");
	}
?>
Ausgabe
eins, ZwEi, DREI, 1, 3.141, 


3. Ermitteln, welche Werte Duplikate sind


Soll bestimmt werden, welche Werte mehrfach vorkommen, kann array_unique() in Kombination mit array_diff_assoc() verwendet werden.
array_unique() entfernt die Duplikate und array_diff_assoc() ermittelt, welche Schlüssel-Wert-Paare im Array ohne Duplikate nicht mehr enthalten sind.
(Auf das Ergebnis von array_diff_assoc() könnte wiederum array_unique() angewandt werden, da andernfalls mehrfach entfernte Duplikate auch mehrmals aufgezählt werden.)
PHP-Code
<?php
	$arr = array(1, 2, 4, 1, 6, 2, 9, 9, 10, 9);
	$unique = array_unique($arr);
	var_dump(array_diff_assoc($arr, $unique));
?>
Ausgabe
array(4) {
  [3]=>
  int(1)
  [5]=>
  int(2)
  [7]=>
  int(9)
  [9]=>
  int(9)
}


4. array_unique() für mehrdimensionale Arrays


Duplikate aus mehrdimensionalem Array entfernen
Die nachfolgende rekursive Funktion entfernt alle Duplikate aus einem mehrdimensionalem Array.
Dabei wird jedes Unterarray für sich behandelt. Enthält demnach Unterarray A eine 1 und auch Unterarray B eine 1, dann taucht die 1 auch nach Anwendung der Funktion in A und B noch immer auf, aber jeweils nur maximal ein Mal.
Die Funktion erhält die Schlüssel so weit wie möglich.
Die Funktion ist nur auf Arrays ausgelegt, die Unterarrays und/oder skalare Werte (string, int, float, boolean) enthalten.
PHP-Code
<?php
	function array_unique_recursive($array) {
		$set = array();
		$out = array();
		foreach ($array as $key=>$val) {
			if (is_array($val)) {
				$out[$key] = array_unique_recursive($val);
			} elseif (!isset($set[$val])) {
				$out[$key] = $val;
				$set[$val] = true;
			}
		}
		return $out;
	}

	$arr = array(1, 2, 4, 1, 1, 2, 9, array(1, 5, 3, 1, 3, 5, 5), 9, 10, 9);
	$arr = array_unique_recursive($arr);
	var_dump($arr);
?>
Ausgabe
array(6) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(4)
  [6]=>
  int(9)
  [7]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(5)
    [2]=>
    int(3)
  }
  [9]=>
  int(10)
}


Die nachfolgende rekursive Funktion verhält sich genauso wie die zuvor genannte, löscht aber zusätzlich Duplikate, die über mehrere Arrays verteilt sind.
Enthält demnach Unterarray A eine 1 und B eine 1, dann ist die 1 nachher nur noch in A enthalten und B ein leeres Array.
PHP-Code
<?php
	function array_unique_recursive_all($array, $found=null) {
		if ($found===null) {
			$found = array();
		}

		$out = array();
		foreach ($array as $key=>$val) {
			if (is_array($val)) {
				$tmp = array_unique_recursive_all($val, $found);
				$out[$key] = $tmp[0];
				$found = $tmp[1];
			} elseif (!isset($found[$val])) {
				$out[$key] = $val;
				$found[$val] = true;
			}
		}
		return array($out, $found);
	}

	$arr = array(1, 2, 4, 1, 6, 2, 9, array(1, 5, 10, 1, 3, 5, 5), 9, 10, array(9, 17), array(1), 9);
	list($arr) = array_unique_recursive_all($arr);
	var_dump($arr);
?>
Ausgabe
array(8) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(4)
  [4]=>
  int(6)
  [6]=>
  int(9)
  [7]=>
  array(3) {
    [1]=>
    int(5)
    [2]=>
    int(10)
    [4]=>
    int(3)
  }
  [10]=>
  array(1) {
    [1]=>
    int(17)
  }
  [11]=>
  array(0) {
  }
}


5. Eigenes array_unqiue()


Um Duplikate zu entfernen, ohne dabei array_unique() zu verwenden, kann eine Kombination aus array_keys() und array_flip() verwendet werden. array_flip() vertauscht Werte und Schlüssel miteinander, sodass etwa aus array('eins'=>1) das Array array(1=>'eins') wird.
Da jeder Schlüssel nur ein Mal definiert sein darf, werden mehrfache Schlüssel automatisch überschrieben.
Die Schlüssel wiederum können mit array_keys() ausgelesen werden.
PHP-Code
<?php
	$arr = array(1, 2, 4, 1, 6, 2, 9, 9, 10);
	$flipped = array_flip($arr);
	$unique = array_keys($flipped);
	var_dump($unique);
?>
Ausgabe
array(6) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(4)
  [3]=>
  int(6)
  [4]=>
  int(9)
  [5]=>
  int(10)
}

Alternativ ist auch die Anwendung einer foreach-Schleife mit passender if/else-Abfrage möglich:
PHP-Code
<?php
	function my_array_unique($arr) {
		$found = array();
		foreach ($arr as $key=>$val) {
			// Abfrage, ob Wert $val bereits mindestens ein Mal gefunden wurde
			if (isset($found[$val])) {
				// falls ja wird der Wert aus dem Array entfernt
				unset($arr[$key]);
			}
			$found[$val] = true;
		}
		return $arr;
	}

	$arr = array(1, 2, 4, 1, 6, 2, 9, 9, 10);
	$arr = my_array_unique($arr);
	var_dump($arr);
?>
Ausgabe
array(6) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(4)
  [4]=>
  int(6)
  [6]=>
  int(9)
  [8]=>
  int(10)
}

Beide zuvor genannten Funktionen eignen sich nur für die Anwendung auf eindimensionale Arrays mit skalaren Werten (Boolean, Integer, String, Float).
Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, verwenden wir Cookies. Durch die weitere Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu. Weitere Informationen zu Cookies erhalten Sie in unserer Datenschutzerklärung. OK