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
)
)
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)));
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.
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'));
?>
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);
}
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 :09encore 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 .
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
)
)
il suffit d'utiliser L'option SORT_REGULAR comme second paramètre.
$uniqueArray = array_unique($array, SORT_REGULAR);
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.
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é
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
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;
}
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.
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.
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"
}
}
* /
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;
j'ai beaucoup réfléchi à ce problème et j'ai déterminé que la solution optimale devrait suivre deux règles.
- pour l'évolutivité, modifier le tableau en place; aucune copie vers un nouveau tableau
- 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.
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