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