Jak usunąć zduplikowane wartości z wielowymiarowej tablicy w PHP

Jak mogę usunąć zduplikowane wartości z wielowymiarowej tablicy w PHP?

Przykładowa tablica:

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
    )

)
Author: Ian, 2008-11-21

17 answers

Jest inny sposób. Nie są zapisywane żadne zmienne pośrednie.

Użyliśmy tego do usuwania duplikatów wyników z różnych nakładających się zapytań.

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
 561
Author: daveilers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-06 16:28:12

Od wersji 5.2.9 można używać array_unique() Jeśli używasz flagi SORT_REGULAR w ten sposób:

array_unique($array, SORT_REGULAR);

To sprawia, że funkcja porównuje elementy dla równości tak, jakby $a == $b były używane, co jest idealne dla Twojego przypadku.

Wyjście

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

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

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

)

Należy jednak pamiętać, że dokumentacja stwierdza:

array_unique() nie jest przeznaczony do pracy na tablicach wielowymiarowych.

 187
Author: Ja͢ck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-30 10:41:12

Miałem podobny problem, ale znalazłem w 100% działające rozwiązanie dla niego.

<?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'));

?>
 51
Author: Rajendrasinh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-14 16:27:59

W inny sposób. Zachowa również klucze.

function array_unique_multidimensional($input)
{
    $serialized = array_map('serialize', $input);
    $unique = array_unique($serialized);
    return array_intersect_key($input, $unique);
}
 23
Author: OIS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-08 08:16:22

Użytkownik komentuje dokumentację array_unique () . Oto jeden z nich:

Kenrbnsn at rbnsn dot com
27-Sep-2005 12: 09

Yet another Array_Unique for multi-demensioned arrays. Testowałem to tylko na dwóch rozkładanych tablicach, ale prawdopodobnie można by to uogólnić na więcej lub użyć rekurencji.

Ta funkcja używa funkcji serialize, array_unique i unserialize do wykonywania praca.


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);
}

To jest z http://ca3.php.net/manual/en/function.array-unique.php#57202 .

 18
Author: Jeremy Ruten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-10 08:04:47

Jeśli "Usuń duplikaty" oznacza "Usuń duplikaty, ale niech tam będzie", rozwiązaniem może być zastosowanie array_unique(...) na "kolumnie identyfikatora" najpierw, a następnie usunięcie w oryginalnej tablicy wszystkich kluczy, które zostały usunięte z tablicy kolumn:

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

Wynik jest następujący:

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

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

)
 11
Author: automatix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-20 23:02:07

Po prostu użyj opcji SORT_REGULAR jako drugiego parametru.

$uniqueArray = array_unique($array, SORT_REGULAR);
 3
Author: anghazi ghermezi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-12 07:18:53

Jeśli chcesz wyeliminować duplikaty na określonych kluczach, takich jak MySQLi id, Oto prosty funciton

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

Punkty Bonusowe Możesz przekazać tablicę klawiszy i dodać zewnętrzny foreach, ale będzie to 2x wolniejsze na dodatkowy klawisz.

 3
Author: r3wt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-14 17:16:14
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);

Spowoduje usunięcie zduplikowanych nazw z tablicy. unique by key

 3
Author: Mahak Choudhary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-14 15:53:49

Jeśli masz taką tablicę:

(users to nazwa tablicy)

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

I chcesz usunąć duplikaty...wtedy:

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

Może być rozwiązaniem: P

 2
Author: Limon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-07 18:45:40

Łatwe do odczytania rozwiązanie, prawdopodobnie nie najskuteczniejsze:

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
Author: pixeline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-10 01:12:48

Wiele osób pytało mnie, jak zrobić unikalną tablicę wielowymiarową. Skorzystałem z twojego komentarza i mi to pomaga.

Po pierwsze, podziękowania dla @jeromegamez @ daveilers za rozwiązanie. Ale za każdym razem, gdy dawałem odpowiedź, pytali mnie, jak to "serialize" i "unserialize" działa. Dlatego chcę podzielić się z wami powodem tego, aby pomóc większej liczbie osób zrozumieć koncepcję stojącą za tym.

Wyjaśniam dlaczego używamy 'serialize' i "unserialize" w krokach:

Krok 1: Konwertuj tablicę wielowymiarową na tablicę jednowymiarową

Aby przekonwertować tablicę wielowymiarową na tablicę jednowymiarową, najpierw Wygeneruj reprezentację strumienia bajtów wszystkich elementów (w tym zagnieżdżonych tablic) wewnątrz tablicy. funkcja serialize () może generować reprezentację strumienia bajtów wartości. Aby wygenerować reprezentację strumienia bajtów wszystkich elementów, wywołaj funkcję serialize () wewnątrz funkcji array_map() jako wywołanie zwrotne funkcja. Rezultatem będzie tablica jednowymiarowa bez względu na to, ile poziomów ma tablica wielowymiarowa.

Krok 2: Utwórz unikalne wartości

Aby ta jednowymiarowa tablica była unikalna, użyj funkcji array_unique ().

Krok 3: Przywróć go do tablicy wielowymiarowej

Chociaż tablica jest teraz unikalna, wartości wyglądają jak reprezentacja strumienia bajtów. Aby przywrócić go z powrotem do tablicy wielowymiarowej, użyj unserialize() funkcja.

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

Jeszcze raz dziękuję za to wszystko.

 1
Author: Manish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-01 11:29:33

Bardzo prosty i logiczny sposób na uniknięcie tablicy wielowymiarowej jest następujący:

Jeśli masz taką tablicę:

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

Użyj foreach, aby rozwiązać ten problem:

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

Da ci następujący wynik:

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

I jeśli chcesz zmienić kolejność klawiszy,

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

Ta operacja da ci ułożone wartości klucza w następujący sposób:

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value3
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value3
            [3] => Value4
        )
)
Mam nadzieję, że to wszystko wyjaśni.
 1
Author: Anand agrawal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-19 13:22:42

Alternatywa dla serialize i unique

$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
Author: Denis Laliberté,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-06 23:04:48

Jeśli masz taką tablicę

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

I chcesz mieć takie tablice:

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

Lub

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

Poniższy kod może pomóc

    $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
Author: milic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-29 17:08:48

Poświęciłem temu problemowi wiele myśli i ustaliłem, że optymalne rozwiązanie powinno być zgodne z dwiema zasadami.

  1. dla skalowalności, zmodyfikuj tablicę w miejscu; nie kopiuj do nowej tablicy
  2. dla wydajności, każde porównanie powinno być wykonane tylko raz

Mając to na uwadze i biorąc pod uwagę wszystkie dziwactwa PHP, poniżej znajduje się rozwiązanie, które wymyśliłem. W przeciwieństwie do innych odpowiedzi, ma możliwość usuwania elementów w oparciu o dowolne klawisze. Wejście tablica ma być kluczami numerycznymi.

$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]);
                }
            }
        }
    }
}

Jedyną wadą jest to, że klucze nie są w porządku po zakończeniu iteracji. Nie jest to problemem, jeśli później używasz tylko pętli foreach, ale jeśli musisz użyć pętli for, możesz umieścić $input = array_values($input); po powyższym, aby zmienić numerację kluczy.

 0
Author: Snake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-05 14:04:48

Jak ludzie mówią array_unique() jest bardzo powolny, oto fragment, którego używam dla tablicy wielowymiarowej jednego poziomu.

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

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

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

Reference first user contributed note of array_unique() strona funkcji w php.net

 0
Author: Anuj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-22 13:07:12