Duplikate aus Arrays entfernen (Thema: PHP Beispiele)

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

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).

Kommentare (0)

Von neu nach alt