
Roxx
Ich muss Zeilen aus meinem Eingabearray entfernen, in denen doppelte Werte in einer bestimmten Spalte vorkommen.
Beispiel-Array:
$array = [
['user_id' => 82, 'ac_type' => 1],
['user_id' => 80, 'ac_type' => 5],
['user_id' => 76, 'ac_type' => 1],
['user_id' => 82, 'ac_type' => 1],
['user_id' => 80, 'ac_type' => 5]
];
Ich möchte filtern nach user_id
um die Eindeutigkeit zu gewährleisten und dieses Ergebnis zu erzielen:
Meine Ausgabe wird also so aussehen:
[
['user_id' => 82, 'ac_type' => 1],
['user_id' => 80, 'ac_type' => 5],
['user_id' => 76, 'ac_type' => 1]
]
Ich habe es schon probiert mit:
$result = array_unique($array, SORT_REGULAR);
und
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
und
$result = array();
foreach ($array as $k => $v) {
$results[implode($v)] = $v;
}
$results = array_values($results);
print_r($results);
aber es gibt immer noch doppelte Zeilen.

mickmackusa
Für ein klareres “minimales, vollständiges, überprüfbares Beispiel” verwende ich das folgende Eingabearray in meinen Demos:
$array = [
['user_id' => 82, 'ac_type' => 1],
['user_id' => 80, 'ac_type' => 5],
['user_id' => 76, 'ac_type' => 1],
['user_id' => 82, 'ac_type' => 2],
['user_id' => 80, 'ac_type' => 5]
];
// elements [0] and [3] have the same user_id, but different ac_type
// elements [1] and [4] have identical row data
-
Zeilen bedingungslos in ein Ergebnisarray verschieben und assoziative Schlüssel der ersten Ebene zuweisen, dann mit neu indizieren array_values()
. Dieser Ansatz überschreibt frühere doppelte Zeilen mit später auftretenden.
array_column-Demo:
var_export(array_values(array_column($array, null, 'user_id')));
für jede Demo:
$result = [];
foreach ($array as $row) {
$result[$row['user_id']] = $row;
}
var_export(array_values($result));
Ausgabe:
[
['user_id' => 82, 'ac_type' => 2], // was input row [3]
['user_id' => 80, 'ac_type' => 5], // was input row [4]
['user_id' => 76, 'ac_type' => 1] // was input row [2]
]
-
Verwenden Sie eine Bedingung oder den NULL-Coalescing-Zuweisungsoperator, um die erste vorkommende Zeile beim Entfernen von Duplikaten beizubehalten.
Demo für foreach null koaleszierende Zuweisungen:
foreach ($array as $a) {
$result[$a['user_id']] ??= $a; // only store if first occurrence of user_id
}
var_export(array_values($result)); // re-index and print
für jede Isset-Demo:
foreach ($array as $a) {
if (!isset($result[$a['user_id']])) {
$result[$a['user_id']] = $a; // only store if first occurrence of user_id
}
}
var_export(array_values($result)); // re-index and print
Ausgabe:
[
['user_id' => 82, 'ac_type' => 1], // was input row [0]
['user_id' => 80, 'ac_type' => 5], // was input row [1]
['user_id' => 76, 'ac_type' => 1] // was input row [2]
]
-
Es ist auch möglich, Daten bedingungslos zu pushen UND eine Bedingung zu vermeiden, aber die Zeilenreihenfolge kann sich zwischen Eingabe und Ausgabe unterscheiden (falls es für Sie wichtig ist).
array_reverse, array_column demo:
var_export(array_values(array_column(array_reverse($array), null, 'user_id')));
array_reduce-Demo:
var_export(
array_values(
array_reduce(
$array,
fn($res, $row) => array_replace([$row['user_id'] => $row], $res),
[]
)
)
);
foreach array_reverse-Demo:
$result = [];
foreach (array_reverse($array) as $row) {
$result[$row['user_id']] = $row;
}
var_export(array_values($result));
Ausgabe:
[
['user_id' => 80, 'ac_type' => 5], // was input row [1]
['user_id' => 82, 'ac_type' => 1], // was input row [0]
['user_id' => 76, 'ac_type' => 1] // was input row [2]
]
Eine Warnung vor einem Randfall, der in diesem Beispiel nicht zum Ausdruck kommt: Wenn Sie Zeilenwerte als Bezeichner verwenden, die bei der Verwendung als Schlüssel beschädigt werden können, führen die oben genannten Techniken zu unzuverlässigen Ergebnissen. Beispielsweise erlaubt PHP keine Float-Werte als Schlüssel (sie verursachen je nach PHP-Version einen Fehler oder werden abgeschnitten). Nur in diesen Randfällen sollten Sie in Erwägung ziehen, ineffiziente, wiederholte Aufrufe von zu verwenden in_array()
Einzigartigkeit zu bewerten.
Verwenden array_unique(..., SORT_REGULAR)
ist nur geeignet, wenn die Eindeutigkeit anhand GESAMTER Datenzeilen bestimmt wird.
array_unique-Demo:
var_export(array_unique($array, SORT_REGULAR));
Ausgabe:
[
['user_id' => 82, 'ac_type' => 1], // was input row [0]
['user_id' => 80, 'ac_type' => 5], // was input row [1]
['user_id' => 76, 'ac_type' => 1] // was input row [2]
['user_id' => 82, 'ac_type' => 2], // was input row [3]
]
$array = [
['user_id'=>82,'ac_type'=>1],
['user_id'=>80,'ac_type'=>5],
['user_id'=>76,'ac_type'=>1],
['user_id'=>82,'ac_type'=>2],
['user_id'=>80,'ac_type'=>6]
];
$array = array_reverse($array);
$v = array_reverse(
array_values(
array_combine(
array_column($array, 'user_id'),
$array
)
)
);
echo '<pre>';
var_dump($v);
Ergebnis:
array(3) {
[0]=>
array(2) {
["user_id"]=>
int(76)
["ac_type"]=>
int(1)
}
[1]=>
array(2) {
["user_id"]=>
int(82)
["ac_type"]=>
int(1)
}
[2]=>
array(2) {
["user_id"]=>
int(80)
["ac_type"]=>
int(5)
}
}
Hat eine Weile gedauert, aber das sollte funktionieren (Erklärung in den Kommentaren):
<?php
/* Example array */
$result = array(
0 => array(
"user_id" => 82,
"ac_type" => 1
),
1 => array(
"user_id" => 80,
"ac_type" => 5
),
2 => array(
"user_id" => 76,
"ac_type" => 1
),
3 => array(
"user_id" => 82,
"ac_type" => 2
),
4 => array(
"user_id" => 80,
"ac_type" => 2
)
);
/* Function to get the keys of duplicate values */
function get_keys_for_duplicate_values($my_arr, $clean = false) {
if ($clean) {
return array_unique($my_arr);
}
$dups = $new_arr = array();
foreach ($my_arr as $key => $val) {
if (!isset($new_arr[$val])) {
$new_arr[$val] = $key;
} else {
if (isset($dups[$val])) {
$dups[$val][] = $key;
} else {
//$dups[$val] = array($key);
$dups[] = $key;
// Comment out the previous line, and uncomment the following line to
// include the initial key in the dups array.
// $dups[$val] = array($new_arr[$val], $key);
}
}
}
return $dups;
}
/* Create a new array with only the user_id values in it */
$userids = array_combine(array_keys($result), array_column($result, "user_id"));
/* Search for duplicate values in the newly created array and return their keys */
$dubs = get_keys_for_duplicate_values($userids);
/* Unset all the duplicate keys from the original array */
foreach($dubs as $key){
unset($result[$key]);
}
/* Re-arrange the original array keys */
$result = array_values($result);
echo '<pre>';
print_r($result);
echo '</pre>';
?>
Aus dieser Funktion wurde die Antwort auf diese Frage entnommen: Holen Sie sich die Schlüssel für doppelte Werte in einem Array
Ausgabe:
Array
(
[0] => Array
(
[user_id] => 82
[ac_type] => 1
)
[1] => Array
(
[user_id] => 80
[ac_type] => 5
)
[2] => Array
(
[user_id] => 76
[ac_type] => 1
)
)

Michael Gedion
Getestetes und funktionierendes Beispiel.
<?php
$details = array('0'=> array('user_id'=>'82', 'ac_type'=>'1'), '1'=> array('user_id'=>'80', 'ac_type'=>'5'), '2'=>array('user_id'=>'76', 'ac_type'=>'1'), '3'=>array('user_id'=>'82', 'ac_type'=>'1'), '4'=>array('user_id'=>'80', 'ac_type'=>'5'));
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
?>
<?php
$details = unique_multidim_array($details,'user_id');
?>
<pre>
<?php print_r($details); ?>
</pre>
Wird ausgegeben:
Array
(
[0] => Array
(
[user_id] => 82
[ac_type] => 1
)
[1] => Array
(
[user_id] => 80
[ac_type] => 5
)
[2] => Array
(
[user_id] => 76
[ac_type] => 1
)
)
von hier genommen http://php.net/manual/en/function.array-unique.php in den von Benutzern beigesteuerten Notizen.
10151400cookie-checkZeilen filtern/entfernen, in denen der Spaltenwert mehr als einmal in einem mehrdimensionalen Array vorkommtyes
Wow, ich sehe die Ablehnung. Irgendein bestimmter Grund?
– Roxx
10. August 2017 um 2:52 Uhr
Ich bekomme diese Ablehnung auch nicht. Schätze, es ist das Risiko, um diese Zeit zu fragen. Viele Benutzer spammen zufällige Stimmen für Abzeichen oder so herum.
– Eiswürfel
10. August 2017 um 2:56 Uhr
@icecub Ich habe versucht, die Frage richtig zu erklären. Habe auch SO nach Antwort gesucht. Auch erwähnt, was ich versucht hatte. Aber trotzdem runtergevotet.
– Roxx
10. August 2017 um 2:58 Uhr
Ich kann nur sehen, dass jemand versucht, den Titel Ihrer Frage zu bearbeiten. Aber das ist es. Lass es mich korrigieren.
– Eiswürfel
10. August 2017 um 2:59 Uhr
Danke, Mann. Ich versuche seit gestern, dieses Problem zu beheben, aber bisher kein Glück.
– Roxx
10. August 2017 um 3:00 Uhr