Zeilen filtern/entfernen, in denen der Spaltenwert mehr als einmal in einem mehrdimensionalen Array vorkommt

Lesezeit: 7 Minuten

Benutzer-Avatar
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.

  • 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

Benutzer-Avatar
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
  1. 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]
    ]
    
  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]
    ]
    
  3. 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]
]

  • Ich bin mir nicht sicher, ob er das will. Er möchte Duplikate nur basierend auf der user_id entfernen. Dadurch wird die erhalten letzte Duplizieren und entfernen Sie alle vorherigen. Ich denke, er möchte die erste Übereinstimmung beibehalten und alle Duplikate danach entfernen?

    – Eiswürfel

    10. August 2017 um 4:12 Uhr

  • Du hast Recht. Wenn dies einen Unterschied zur tatsächlichen Anwendung macht, muss ich es überarbeiten, um die ersten Vorkommen beizubehalten.

    – mickmackusa

    10. August 2017 um 4:13 Uhr

  • Wie auch immer, +1 von mir. Ich habe tatsächlich ein paar Dinge aus Ihrer Antwort gelernt. Vielen Dank 🙂

    – Eiswürfel

    10. August 2017 um 4:20 Uhr

  • Danke für deine Antwort.

    – Roxx

    10. August 2017 um 18:45 Uhr

  • Hübsch! Sehr hilfreich! +1.

    – Michael GEDION

    11. August 2017 um 6:21 Uhr

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

)

Benutzer-Avatar
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.

1015140cookie-checkZeilen filtern/entfernen, in denen der Spaltenwert mehr als einmal in einem mehrdimensionalen Array vorkommt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy