1. GROUP BY
ein Schlüssel
Diese Funktion funktioniert wie GROUP BY
für ein Array, jedoch mit einer wichtigen Einschränkung: Es ist nur eine Gruppierung "column" ( $identifier
) möglich.
function arrayUniqueByIdentifier(array $array, string $identifier)
{
$ids = array_column($array, $identifier);
$ids = array_unique($ids);
$array = array_filter($array,
function ($key, $value) use($ids) {
return in_array($value, array_keys($ids));
}, ARRAY_FILTER_USE_BOTH);
return $array;
}
2. Erkennen der eindeutigen Zeilen für eine Tabelle (zweidimensionales Array)
Diese Funktion dient zum Filtern von "Zeilen". Wenn wir sagen, ein zweidimensionales Array ist eine Tabelle, dann ist jedes Element eine Zeile. Mit dieser Funktion können wir also die duplizierten Zeilen entfernen. Zwei Zeilen (Elemente der ersten Dimension) sind gleich, wenn alle Spalten (Elemente der zweiten Dimension) gleich sind. Für den Vergleich von "Spalten" -Werten gilt: Wenn ein Wert von einem einfachen Typ ist , wird der Wert selbst beim Vergleichen verwendet; sonst seine Art ( array
, object
, resource
, unknown type
) verwendet.
Die Strategie ist einfach: Erstellen Sie aus dem ursprünglichen Array ein flaches Array, wobei die Elemente implode
d "Spalten" des ursprünglichen Arrays sind. dann bewerben array_unique(...)
Sie sich darauf; und als letztes verwenden Sie die erkannten IDs zum Filtern des ursprünglichen Arrays.
function arrayUniqueByRow(array $table = [], string $implodeSeparator)
{
$elementStrings = [];
foreach ($table as $row) {
$elementPreparedForImplode = array_map(
function ($field) {
$valueType = gettype($field);
$simpleTypes = ['boolean', 'integer', 'double', 'float', 'string', 'NULL'];
$field = in_array($valueType, $simpleTypes) ? $field : $valueType;
return $field;
}, $row
);
$elementStrings[] = implode($implodeSeparator, $elementPreparedForImplode);
}
$elementStringsUnique = array_unique($elementStrings);
$table = array_intersect_key($table, $elementStringsUnique);
return $table;
}
Es ist auch möglich, den Vergleich zu verbessern und die Klasse des "Spalten" -Werts zu erkennen, wenn es sich um einen Typ handelt object
.
Das $implodeSeparator
sollte mehr oder weniger komplex sein, zB spl_object_hash($this)
.
3. Erkennen der Zeilen mit eindeutigen Bezeichnerspalten für eine Tabelle (zweidimensionales Array)
Diese Lösung basiert auf der zweiten. Jetzt muss die gesamte "Zeile" nicht eindeutig sein. Zwei "Zeilen" (Elemente der ersten Dimension) sind jetzt gleich, wenn alle relevanten "Felder" (Elemente der zweiten Dimension) der einen "Zeile" gleich den entsprechenden "Feldern" (Elemente mit demselben Schlüssel) sind.
Die "relevanten" "Felder" sind die "Felder" (Elemente der zweiten Dimension), die einen Schlüssel haben, der einem der Elemente der übergebenen "Bezeichner" entspricht.
function arrayUniqueByMultipleIdentifiers(array $table, array $identifiers, string $implodeSeparator = null)
{
$arrayForMakingUniqueByRow = $removeArrayColumns($table, $identifiers, true);
$arrayUniqueByRow = $arrayUniqueByRow($arrayForMakingUniqueByRow, $implodeSeparator);
$arrayUniqueByMultipleIdentifiers = array_intersect_key($table, $arrayUniqueByRow);
return $arrayUniqueByMultipleIdentifiers;
}
function removeArrayColumns(array $table, array $columnNames, bool $isWhitelist = false)
{
foreach ($table as $rowKey => $row) {
if (is_array($row)) {
if ($isWhitelist) {
foreach ($row as $fieldName => $fieldValue) {
if (!in_array($fieldName, $columnNames)) {
unset($table[$rowKey][$fieldName]);
}
}
} else {
foreach ($row as $fieldName => $fieldValue) {
if (in_array($fieldName, $columnNames)) {
unset($table[$rowKey][$fieldName]);
}
}
}
}
}
return $table;
}