it-swarm.com.de

So entfernen Sie doppelte Werte aus einem mehrdimensionalen Array in PHP

Wie kann ich doppelte Werte aus einem mehrdimensionalen Array in PHP entfernen?

Beispielarray:

Array
(
    [0] => Array
    (
        [0] => abc
        [1] => def
    )

    [1] => Array
    (
        [0] => ghi
        [1] => jkl
    )

    [2] => Array
    (
        [0] => mno
        [1] => pql
    )

    [3] => Array
    (
        [0] => abc
        [1] => def
    )

    [4] => Array
    (
        [0] => ghi
        [1] => jkl
    )

    [5] => Array
    (
        [0] => mno
        [1] => pql
    )

)
284
Ian

Hier ist ein anderer Weg. Es werden keine Zwischenvariablen gespeichert.

Wir haben dies verwendet, um Ergebnisse aus verschiedenen überlappenden Abfragen zu desuplizieren.

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
608
daveilers

Seit 5.2.9 können Sie array_unique() verwenden, wenn Sie das Flag SORT_REGULAR Folgendermaßen verwenden:

array_unique($array, SORT_REGULAR);

Dadurch vergleicht die Funktion Elemente auf Gleichheit, als würde $a == $b Verwendet, was für Ihren Fall perfekt ist.

Ausgabe

Array
(
    [0] => Array
        (
            [0] => abc
            [1] => def
        )

    [1] => Array
        (
            [0] => ghi
            [1] => jkl
        )

    [2] => Array
        (
            [0] => mno
            [1] => pql
        )

)

Beachten Sie jedoch, dass die Dokumentation besagt:

array_unique() ist nicht für mehrdimensionale Arrays vorgesehen.

215
Ja͢ck

Ich hatte ein ähnliches Problem, aber ich fand eine 100% funktionierende Lösung dafür.

<?php
    function super_unique($array,$key)
    {
       $temp_array = [];
       foreach ($array as &$v) {
           if (!isset($temp_array[$v[$key]]))
           $temp_array[$v[$key]] =& $v;
       }
       $array = array_values($temp_array);
       return $array;

    }


$arr="";
$arr[0]['id']=0;
$arr[0]['titel']="ABC";
$arr[1]['id']=1;
$arr[1]['titel']="DEF";
$arr[2]['id']=2;
$arr[2]['titel']="ABC";
$arr[3]['id']=3;
$arr[3]['titel']="XYZ";

echo "<pre>";
print_r($arr);
echo "unique*********************<br/>";
print_r(super_unique($arr,'titel'));

?>
58
Rajendrasinh

Ein anderer Weg. Bewahrt auch Schlüssel.

function array_unique_multidimensional($input)
{
    $serialized = array_map('serialize', $input);
    $unique = array_unique($serialized);
    return array_intersect_key($input, $unique);
}
28
OIS

Die Benutzerkommentare in der Dokumentation array_unique () haben viele Lösungen dafür. Hier ist einer von ihnen:

kenrbnsn bei rbnsn dot com
27.09.2005, 12:09 Uhr

Noch eine Array_Unique für mehrdimensionierte Arrays. Ich habe dies nur an zweidimensionalen Arrays getestet, aber es könnte wahrscheinlich für mehr verallgemeinert oder zur Verwendung von Rekursion gemacht werden.

Diese Funktion verwendet die Funktionen serialize, array_unique und unserialize, um die Arbeit auszuführen.


function multi_unique($array) {
    foreach ($array as $k=>$na)
        $new[$k] = serialize($na);
    $uniq = array_unique($new);
    foreach($uniq as $k=>$ser)
        $new1[$k] = unserialize($ser);
    return ($new1);
}

Dies ist von http://ca3.php.net/manual/en/function.array-unique.php#57202 .

20
Jeremy Ruten

Wenn "Duplikate entfernen" "Duplikate entfernen, aber dort lassen" bedeutet, könnte eine Lösung darin bestehen, zuerst das array_unique(...) auf die "Identifiziererspalte" anzuwenden und dann im ursprünglichen Array alle Schlüssel zu entfernen, die wurden aus dem Spaltenarray entfernt:

$array = [
    [
        'id' => '123',
        'foo' => 'aaa',
        'bar' => 'bbb'
    ],
    [
        'id' => '123',
        'foo' => 'ccc',
        'bar' => 'ddd'
    ],
    [
        'id' => '567',
        'foo' => 'eee',
        'bar' => 'fff'
    ]
];

$ids = array_column($array, 'id');
$ids = array_unique($ids);
$array = array_filter($array, function ($key, $value) use ($ids) {
    return in_array($value, array_keys($ids));
}, ARRAY_FILTER_USE_BOTH);

Das Ergebnis ist:

Array
(
    [0] => Array
        (
            [id] => 123
            [foo] => aaa
            [bar] => bbb
        )

    [2] => Array
        (
            [id] => 567
            [foo] => eee
            [bar] => fff
        )

)
13
automatix
Array
(
    [0] => Array
        (
            [id] => 1
            [name] => john
        )

    [1] => Array
        (
            [id] => 2
            [name] => smith
        )

    [2] => Array
        (
            [id] => 3
            [name] => john
        )

    [3] => Array
        (
            [id] => 4
            [name] => robert
        )

)

$temp = array_unique(array_column($array, 'name'));
$unique_arr = array_intersect_key($array, $temp);

Dadurch werden die doppelten Namen aus dem Array entfernt. eindeutig per Schlüssel

8
Mahak Choudhary

wenn Sie Duplikate auf bestimmten Schlüsseln, z. B. einer mysqli-id, entfernen müssen, finden Sie hier eine einfache Funktion

function search_array_compact($data,$key){
    $compact = [];
    foreach($data as $row){
        if(!in_array($row[$key],$compact)){
            $compact[] = $row;
        }
    }
    return $compact;
}

Bonuspunkte Sie können eine Reihe von Schlüsseln übergeben und einen äußeren foreach hinzufügen, aber es wird pro zusätzlichen Schlüssel 2x langsamer sein.

3
r3wt

Verwenden Sie einfach die Option SORT_REGULAR als zweiten Parameter.

$uniqueArray = array_unique($array, SORT_REGULAR);
3

wenn Sie ein Array wie dieses haben:

(Benutzer ist der Name des Arrays)

Array=>
 [0] => (array)
   'user' => 'john'
   'age' => '23'
 [1] => (array)
  'user' => 'jane'
  'age' => '20'
 [2]=> (array)
  'user' => 'john'
  'age' => '23'

und Du willst Duplikate löschen ... dann:

$serialized = array();
for ($i=0; $i < sizeof($users); $i++) { 
  $test = in_array($users['user'], $serialized);
    if ($test == false) {
      $serialized[] = $users['user'];
    }
 }

kann eine Lösung sein: P

2
Limon

Eine einfach zu lesende Lösung, wahrscheinlich nicht die effizienteste:

function arrayUnique($myArray){
    if(!is_array($myArray))
        return $myArray;

    foreach ($myArray as &$myvalue){
        $myvalue=serialize($myvalue);
    }

    $myArray=array_unique($myArray);

    foreach ($myArray as &$myvalue){
        $myvalue=unserialize($myvalue);
    }

    return $myArray;

} 
1
pixeline

Ein sehr einfacher und logischer Weg, um ein mehrdimensionales Array eindeutig zu machen, ist folgender:

Wenn Sie ein Array wie dieses haben:

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value1
            [3] => Value3
            [4] => Value1
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value1
            [3] => Value3
            [4] => Value4
        )
)

benutze foreach um das zu lösen:

foreach($array as $k=>$v){
    $unique=array_unique($v);
    $array[$k]=$unique;
}

es wird folgendes Ergebnis liefern:

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [3] => Value3
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [3] => Value3
            [4] => Value4
        )
)

und wenn Sie die Reihenfolge der Schlüssel ändern möchten,

foreach($array as $k=>$v){
    $unique= array_values(array_unique($v));
    $array[$k]=$unique;
}

Diese Operation gibt Ihnen so angeordnete Schlüsselwerte:

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value3
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value3
            [3] => Value4
        )
)

Ich hoffe das wird alles klären.

1
Anand agrawal

Viele Leute fragten mich, wie man ein einzigartiges mehrdimensionales Array erstellt. Ich habe Bezug auf Ihren Kommentar genommen und es hilft mir.

Zunächst einmal vielen Dank an @jeromegamez @daveilers für Ihre Lösung. Aber jedes Mal, wenn ich die Antwort gab, fragten sie mich, wie das "serialisieren" und "unserialisieren" funktioniert. Deshalb möchte ich den Grund dafür mit Ihnen teilen, damit mehr Menschen das Konzept dahinter verstehen.

Ich erkläre, warum wir "serialisieren" und "unserialisieren" in Schritten verwenden:

Schritt 1: Konvertieren Sie das mehrdimensionale Array in ein eindimensionales Array

Um das mehrdimensionale Array in ein eindimensionales Array zu konvertieren, generieren Sie zunächst eine Byte-Stream-Darstellung aller Elemente (einschließlich verschachtelter Arrays) innerhalb des Arrays. Die Funktion serialize () kann eine Byte-Stream-Darstellung eines Werts generieren. Um eine Byte-Stream-Darstellung aller Elemente zu generieren, rufen Sie die Funktion serialize () in der Funktion array_map () als Rückruffunktion auf. Das Ergebnis ist ein eindimensionales Array, unabhängig von der Anzahl der Ebenen des mehrdimensionalen Arrays.

Schritt 2: Machen Sie die Werte eindeutig

Verwenden Sie die Funktion array_unique (), um dieses eindimensionale Array eindeutig zu machen.

Schritt 3: Wiederherstellen des mehrdimensionalen Arrays

Obwohl das Array jetzt eindeutig ist, sehen die Werte wie eine Byte-Stream-Darstellung aus. Verwenden Sie die Funktion unserialize (), um das mehrdimensionale Array wiederherzustellen.

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));

Nochmals vielen Dank für all das.

1
Manish

Ich habe viel über dieses Problem nachgedacht und festgestellt, dass die optimale Lösung zwei Regeln folgen sollte.

  1. Ändern Sie aus Gründen der Skalierbarkeit das Array. Kein Kopieren in ein neues Array
  2. Für die Leistung sollte jeder Vergleich nur einmal durchgeführt werden

In diesem Sinne und angesichts all der Macken von PHP ist unten die Lösung aufgeführt, die ich mir ausgedacht habe. Im Gegensatz zu einigen anderen Antworten können Elemente basierend auf den gewünschten Schlüsseln entfernt werden. Es wird erwartet, dass das Eingabearray aus Zifferntasten besteht.

$count_array = count($input);
for ($i = 0; $i < $count_array; $i++) {
    if (isset($input[$i])) {
        for ($j = $i+1; $j < $count_array; $j++) {
            if (isset($input[$j])) {
                //this is where you do your comparison for dupes
                if ($input[$i]['checksum'] == $input[$j]['checksum']) {
                    unset($input[$j]);
                }
            }
        }
    }
}

Der einzige Nachteil ist, dass die Schlüssel nach Abschluss der Iteration nicht in Ordnung sind. Dies ist kein Problem, wenn Sie später nur foreach-Schleifen verwenden. Wenn Sie jedoch eine for-Schleife verwenden müssen, können Sie $input = array_values($input); nach den obigen Anweisungen einfügen, um die Schlüssel neu zu nummerieren.

0
Snake

Wenn Sie ein Array wie dieses haben

data = array
(
[0] => array
(
    [subject] => a
    [object] => c
),
[1] => array
(
    [subject] => b
    [object] => d
),
[2] => array
(
    [subject] => d
    [object] => b
),
[3] => array
(
    [subject] => d
    [object] => c
),
[4] => array
(
    [subject] => c
    [object] => a
),
[5] => array
(
    [subject] => c
    [object] => d
)
)

und Sie möchten Arrays wie folgt erhalten:

data = array
(
[0] => array
(
    [subject] => a
    [object] => c
),
[1] => array
(
    [subject] => b
    [object] => d
),
[2] => array
(
    [subject] => d
    [object] => c
)
)

oder

data = array
(
[0] => array
(
    [subject] => d
    [object] => b
),
[1] => array
(
    [subject] => c
    [object] => a
),
[2] => array
(
    [subject] => c
    [object] => d
)
)

ein folgender Code kann helfen

    $data1 = array();
    $data1 = $data;
    for($q=0;$q<count($data);$q++)
    {
            for($p=0;$p<count($data1);$p++)
            {
                    if (($data[$q]["subject"] == $data1[$p]["object"]) && ($data[$q]["object"] == $data1[$p]["subject"]))
                    {
                            $data1[$p]["subject"] = $data[$q]["subject"];
                            $data1[$p]["object"] = $data[$q]["object"];
                    }
            }
    }
    $data1 = array_values(array_map("unserialize", array_unique(array_map("serialize", $data1))));
    $data = $data1;
0
milic

Eine Alternative zu serialisieren und einzigartig

$test = [
    ['abc','def'],
    ['ghi','jkl'],
    ['mno','pql'],
    ['abc','def'],
    ['ghi','jkl'],
    ['mno','pql'],
];

$result = array_reduce(
    $test,
    function($carry,$item){
        if(!in_array($item,$carry)) {
            array_Push($carry,$item);
        }
        return $carry;
    },
    []
);

var_dump($result);

/*
 php unique.php
array(3) {
    [0] =>
        array(2) {
            [0] =>
                string(3) "abc"
            [1] =>
                string(3) "def"
        }
    [1] =>
        array(2) {
            [0] =>
                string(3) "ghi"
            [1] =>
                string(3) "jkl"
        }
    [2] =>
        array(2) {
              [0] =>
                  string(3) "mno"
              [1] =>
                  string(3) "pql"
        }
}

* /

0

Da die Leute sagen, dass array_unique() sehr langsam ist, ist hier ein Ausschnitt, den ich für ein mehrdimensionales Array mit einer Ebene verwende.

$serialized_array = array_map("serialize", $input);

foreach ($serialized_array as $key => $val) {
     $result[$val] = true;
}

$output = array_map("unserialize", (array_keys($result)));

Referenz Der erste Benutzer hat eine Notiz von array_unique()Funktionsseite in php.net beigetragen

0
Anuj