Php: how to compute the different between two arrays of “similar” objects?

旧街凉风 提交于 2020-01-24 12:28:07

问题


I have an array of objects $tab that are "rows" of a table (i.e. you can access each column through "$tab[$i]->columnname.

I have another array of objects $tab_json that is the return of an AJAX call, and that contains, too, "rows" of a table (i.e. you can access each column through "$tab_json[$i]->columnname.

Both arrays contain exactly the same colums, but I would just like to "guess" which ones in $tab are not present in $tab_json.

Of course I know array-intersect and array-diff functions, but they do not seem to work well on objects comparison. Unless I'm wrong?

Here's a sample that I'd like to work, but there's a Php exception:

tab_json = PHP Catchable fatal error:  Object of class stdClass could not be converted to string in sample.php on line 112

Just copy paste it and run it into a file (php -f filename.php). Any idea how I should do?

<?php
$tab = array(
    (object)array(
        'id'          => 1,
        'titre'       => "Anchois",
        'attributs'   => array()
    ),  
    (object)array(
        'id'          => 4,
        'titre'       => "Jambon",
        'attributs'   => array()
    ),  
    (object)array(
        'id'           => 12, 
        'titre'        => "La Cabro d'or",
        'attributs'    => array(
            (object)array("id" => 1), 
            (object)array("id" => 8)
        )   
    )   
);


$tab_json = array (
    (object)array(
        'id' => 1,
        'titre' => 'Anchois',
        'attributs' =>
        array (
        ),  
    ),  
    (object)array(
        'id' => 4,
        'titre' => 'Jambon',
        'attributs' =>
        array (
        ),  
    ),  
    (object)array(
        'id' => 12, 
        'titre' => 'La Cabro d\'or',
        'attributs' =>
        array (
        ),  
    ),  
    (object)array(
        'id' => 25, 
        'titre' => 'Vin rouge ou rosé',
        'attributs' =>
        array (
        ),  
    ),  
    (object)array(
        'id' => 22, 
        'titre' => 'Crème oignons lardons',
        'attributs' =>
        array (
            (object)array(
                'id' => 1,
            ),  
            (object)array(
                'id' => 2,
            ),  
        ),  
    )   
);
echo "tab = "; var_export($tab); echo "\n";
echo "tab_json = "; var_export($tab_json); echo "\n";
echo "tab_json = "; var_export(array_diff($tab_json,$tab)); echo "\n";
?>

回答1:


You can use array_udiff:

$difference = array_udiff($tab, $tab_json, function($a, $b) {
    return $a == $b;
});

The simple array_diff can't be used because it only compares string values identically. PHP 5.3 is required to run this sample, but you can tweak it to PHP 5.2 moving the closure to an external function and passing the name of it as the third parameter on array_udiff.

Note that the order on array_udiff matters. If you pass $tab_json first you can get different results.




回答2:


I've made the function that seems to compare "ok": I "concatenate" the properties of both arrays to make "strings" then use the strcmp() function to return the result. So, when the values are different they're changed to string, and when it comes to "sub" arrays, they're converted to string = "Array" so the comparison == 0 so the "sub" arrays are ignored (which is precisely what I wanted).

It works. If you find an example that could show me that it doesn't work, please share it with me in a comment. Thanks!

$difference = array_udiff($tab_json, $tab, function($a, $b) {
    $d=array_diff_assoc(get_object_vars($a), get_object_vars($b));
    if (count($d)>0) {
        $s0='';
        $s1='';
        foreach ($d as $k=>$val) {
            $r0=(string)$val;
            $r1=(string)$b->$k;
            $l0 = mb_strlen($r0);
            $l1 = mb_strlen($r1);
            for (;$l0<$l1;$l0++) {
                $r0=' '.$r0;
            }   
            for (;$l1<$l0;$l1++) {
                $r1=' '.$r1;
            }   
            $s0.=$r0;
            $s1.=$r1;
        }   
        return strcmp($s0,$s1);
    }   
    return 0;
});
echo "difference = "; var_export($difference); echo "\n";


来源:https://stackoverflow.com/questions/10269932/php-how-to-compute-the-different-between-two-arrays-of-similar-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!