Comment supprimer les valeurs dupliquées d'un tableau multidimensionnel en PHP

Comment puis-je supprimer les valeurs dupliquées d'un tableau multidimensionnel en PHP?

exemple de tableau:

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
    )

)
255
demandé sur Ian 2008-11-21 05:50:30

17 réponses

Voici une autre façon. Aucune variable intermédiaire n'est sauvegardée.

nous avons utilisé ceci pour dé-dupliquer les résultats d'une variété de requêtes se chevauchant.

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
561
répondu daveilers 2015-03-06 16:28:12

depuis 5.2.9 vous pouvez utiliser array_unique() si vous utilisez le drapeau SORT_REGULAR comme suit:

array_unique($array, SORT_REGULAR);

cela rend la fonction Comparer des éléments pour l'égalité comme si $a == $b étaient utilisés, ce qui est parfait pour votre cas.

Sortie

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

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

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

)

gardez à l'esprit, cependant, que la documentation stipule:

array_unique() n'est pas destiné à fonctionner sur des tableaux multidimensionnels.

187
répondu Ja͢ck 2017-05-30 10:41:12

j'ai eu un problème similaire, mais j'ai trouvé une solution à 100%.

<?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
répondu Rajendrasinh 2017-12-14 16:27:59

D'une autre façon. Préserver les touches.

function array_unique_multidimensional($input)
{
    $serialized = array_map('serialize', $input);
    $unique = array_unique($serialized);
    return array_intersect_key($input, $unique);
}
23
répondu OIS 2008-12-08 08:16:22

les commentaires de l'utilisateur sur la documentation array_unique () ont de nombreuses solutions à ce problème. En voici un:

kenrbnsn at rbnsn dot com

27-Sep-2005 12 :09

encore un autre Array_Unique pour les arrays multi-demensioned. Je ne l'ai testé que sur des tableaux à deux démences, mais il pourrait probablement être généralisé pour plus, ou fait pour utiliser la récursion.

cette fonction utilise les fonctions serialize, array_unique, et unserialize pour faire le travail.


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

c'est de http://ca3.php.net/manual/en/function.array-unique.php#57202 .

18
répondu Jeremy Ruten 2017-08-10 08:04:47

si "remove duplicates" signifie "remove duplicates, but let one there", une solution pourrait être d'appliquer le array_unique(...) sur la" colonne d'identification "d'abord et puis de supprimer dans le tableau original toutes les clés, qui ont été retirées du tableau de colonne:

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

le résultat est:

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

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

)
11
répondu automatix 2016-05-20 23:02:07

il suffit d'utiliser L'option SORT_REGULAR comme second paramètre.

$uniqueArray = array_unique($array, SORT_REGULAR);
3
répondu anghazi ghermezi 2015-03-12 07:18:53

si vous avez besoin d'éliminer les doubles sur des clés spécifiques, comme un id mysqli, voici une fonction simple

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

Points Bonus Vous pouvez passer un tableau de touches et Ajouter un foreach externe, mais il sera 2X plus lent par touche supplémentaire.

3
répondu r3wt 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);

cela supprimera les noms dupliqués du tableau. unique par clé

3
répondu Mahak Choudhary 2018-05-14 15:53:49

si vous avez un tableau comme ceci:

(les utilisateurs est le nom du tableau)

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

et vous voulez supprimer les doublons...puis:

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

peut être une solution: P

2
répondu Limon 2015-08-07 18:45:40

une solution facile à lire, probablement pas la plus efficace:

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
répondu pixeline 2010-01-10 01:12:48

beaucoup de personnes m'ont demandé comment faire un tableau multidimensionnel Unique. J'ai pris la référence de votre commentaire et il m'aide.

tout d'abord, merci à @jeromegamez @daveilers pour votre solution. Mais à chaque fois j'ai donné la réponse, ils m'ont demandé comment cette "sérialiser" et " unserialize œuvres. C'est pourquoi je veux partager la raison de cela avec vous afin qu'il aidera plus de gens à comprendre le concept derrière cela.

j'explique pourquoi nous utilisons 'serialize' et 'unserialize' dans les étapes:

Étape 1: convertir le tableau multidimensionnel en tableau unidimensionnel

pour convertir le tableau multidimensionnel en un tableau unidimensionnel, il faut d'abord générer une représentation byte stream de tous les éléments (y compris les tableaux imbriqués) à l'intérieur du tableau. la fonction serialize () peut générer une représentation byte stream d'une valeur. Pour générer la représentation byte stream de tous les éléments, appelez la fonction serialize() la fonction à l'intérieur de array_map() comme une fonction de rappel. Le résultat sera un tableau unidimensionnel n'importe comment beaucoup de niveaux, le tableau multidimensionnel.

Étape 2: Rendre les valeurs uniques

pour rendre ce tableau unidimensionnel unique, utilisez la fonction array_unique ().

Etape 3: revenir au tableau multidimensionnel

bien que le tableau soit maintenant unique, les valeurs ressemblent à une représentation byte stream. Pour revenir au tableau multidimensionnel, utilisez la fonction unserialize ().

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

Merci encore pour tout cela.

1
répondu Manish 2016-09-01 11:29:33

une façon très simple et logique de rendre Unique un tableau multidimensionnel est la suivante,

si vous avez un tableau comme celui-ci:

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

utilisez foreach pour résoudre ce problème:

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

il vous donnera le résultat suivant:

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

et si vous voulez réarranger l'ordre des touches,

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

cette opération vous donnera des valeurs clés arrangées comme ceci:

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

j'espère que tout sera éclairci.

1
répondu Anand agrawal 2018-01-19 13:22:42

une alternative à la sérialisation et 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
répondu Denis Laliberté 2014-11-06 23:04:48

si vous avez un tableau comme celui-ci

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

et vous voulez obtenir des tableaux comme ceci:

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

ou

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

un code suivant peut aider

    $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
répondu milic 2014-11-29 17:08:48

j'ai beaucoup réfléchi à ce problème et j'ai déterminé que la solution optimale devrait suivre deux règles.

  1. pour l'évolutivité, modifier le tableau en place; aucune copie vers un nouveau tableau
  2. pour les performances, chaque comparaison ne doit être effectuée qu'une seule fois."

avec cela à l'esprit et compte tenu de toutes les bizarreries de PHP, voici la solution que j'ai trouvé. Contrairement à certaines autres réponses, il a la capacité pour supprimer les éléments basés sur la(Les) clé (s) que vous voulez. Le tableau d'entrée est censé être des clés numériques.

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

le seul inconvénient est que les clés ne sont pas dans l'ordre lorsque l'itération est terminée. Ce n'est pas un problème si vous utilisez par la suite seulement des boucles foreach, mais si vous avez besoin d'utiliser une boucle for, vous pouvez mettre $input = array_values($input); après ce qui précède pour renuméroter les clés.

0
répondu Snake 2015-03-05 14:04:48

comme disent les gens array_unique() est très lent, voici un extrait que j'utilise pour un tableau multidimensionnel de niveau.

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

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

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

référence première contribution de l'utilisateur note de la fonction array_unique() dans php.net

0
répondu Anuj 2015-05-22 13:07:12