2011-05-19 3 views
2

Bonjour, j'ai deux tableaux imbriqués et je dois trouver la différence entre le tableau de référence et le tableau de données. J'utilise la fonction array_dif_assoc, et je suis incapable d'obtenir la bonne différence, je ne sais pas pourquoi je suis incapable de l'obtenir. Quelqu'un pourrait-il m'aider si je commets une erreur ou si je dois le faire récursivement?Utilisation de la fonction array_diff_assoc dans PHP

$allCoursesAvailable = array(array('id'=>0,'name'=>'Select-One'), array('id'=>1,'name'=>'course1'),array('id'=>1,'name'=>'course2'),array('id'=>3,'name'=>'course3')); 

$allCoursesforUser = array(array('id'=>0,'name'=>'Select-One'), array('id'=>1,'name'=>'course1'),array('id'=>4,'name'=>'course4'),array('id'=>5,'name'=>'course5'),array('id'=>6,'name'=>'course4')); 

echo '<pre>';print_r(array_diff_assoc($allCoursesAvailable,$allCoursesforUser)); 

Je reçois un tableau vide avec ceci. Quand j'utilise array_diff_assoc, j'aurais dû avoir les tableaux portant course2 et course3, car ils ne font pas partie du second tableau. Est-ce que je manque une certaine logique sur la fin de PHP ???

Répondre

4

Vous pouvez toujours commencer par lire le manuel PHP.

Pour array_diff_assoc (sur http://php.net/manual/en/function.array-diff-assoc.php) il est dit que this function only checks one dimension of a n-dimensional array. Of course you can check deeper dimensions by using, for example, array_diff_assoc($array1[0], $array2[0]);.

solution fournie dans les commentaires des utilisateurs (ce qui fonctionne):

55 points php à iMARS dot com 17-Mar-2009 03 : 09 J'ai travaillé sur array_diff_assoc_recursive() mentionné par chinello à gmail dot com et je pense qu'il pourrait être utile de mentionner ici. J'ai écrit une douzaine de cas de test et il semble plutôt bien résister.

<?php 
// dwarven Differences: 
// * Replaced isset() with array_key_exists() to account for keys with null contents 

// 55 dot php at imars dot com Differences: 
// Key differences: 
// * Removed redundant test; 
// * Returns false bool on exact match (not zero integer); 
// * Use type-precise comparison "!==" instead of loose "!="; 
// * Detect when $array2 contains extraneous elements; 
// * Returns "before" and "after" instead of only "before" arrays on mismatch. 

function array_compare($array1, $array2) { 
    $diff = false; 
    // Left-to-right 
    foreach ($array1 as $key => $value) { 
     if (!array_key_exists($key,$array2)) { 
      $diff[0][$key] = $value; 
     } elseif (is_array($value)) { 
      if (!is_array($array2[$key])) { 
        $diff[0][$key] = $value; 
        $diff[1][$key] = $array2[$key]; 
      } else { 
        $new = array_compare($value, $array2[$key]); 
        if ($new !== false) { 
         if (isset($new[0])) $diff[0][$key] = $new[0]; 
         if (isset($new[1])) $diff[1][$key] = $new[1]; 
        }; 
      }; 
     } elseif ($array2[$key] !== $value) { 
      $diff[0][$key] = $value; 
      $diff[1][$key] = $array2[$key]; 
     }; 
}; 
// Right-to-left 
foreach ($array2 as $key => $value) { 
     if (!array_key_exists($key,$array1)) { 
      $diff[1][$key] = $value; 
     }; 
     // No direct comparsion because matching keys were compared in the 
     // left-to-right loop earlier, recursively. 
}; 
return $diff; 
}; 
?> 
+0

vous avez à factoriser initialisation diff $ diff = array(), parce que le retour de la fonction tableau | bool au lieu de array() ne sont pas une bonne solution, je pense. – alexglue

0

Je pense que les diffs de tableau intégrés sont peu profonds, ce qui signifie qu'ils ne vérifient que le premier niveau et ne regardent pas les tableaux à l'intérieur.

Quelques solutions ici:

PHP - Mutidimensional array diff

0

Vous ne devriez pas utiliser _assoc mais le array_diff normal ou array_intersect, car sinon il comparera l'ordre du tableau extérieur et non seulement le contenu.

également array_diff ne fonctionne pas vraiment avec sous-tableaux, et vous aurez besoin d'une solution de contournement:

print_r(
    array_map("unserialize", 
    array_diff(
     array_map("serialize", $allCoursesAvailable), 
     array_map("serialize", $allCoursesforUser) 
    ) 
) 
); 

qui vous donnerait:

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

[3] => Array 
    (
     [id] => 3 
     [name] => course3 
    ) 

Je ne sais pas si c'est ce que vous vouliez. Et le faire manuellement pourrait être conseillé encore.

Questions connexes