marcelo2605
marcelo2605

Reputation: 2794

Comparing two object arrays with array_udiff

Array 1: $tags_result

    array (size=4)
  0 => 
    object(stdClass)[8]
      public 'id_tag' => string '2' (length=1)
      public 'tag' => string 'tag 1' (length=5)
  1 => 
    object(stdClass)[9]
      public 'id_tag' => string '5' (length=1)
      public 'tag' => string 'tag 4' (length=5)
  2 => 
    object(stdClass)[10]
      public 'id_tag' => string '6' (length=1)
      public 'tag' => string 'tag 7' (length=5)
  3 => 
    object(stdClass)[11]
      public 'id_tag' => string '7' (length=1)
      public 'tag' => string 'tag 9' (length=5)

Array 2: $post_tags_result

    array (size=2)
  0 => 
    object(stdClass)[5]
      public 'id_tag' => string '2' (length=1)
      public 'tag' => string 'tag 1' (length=5)
  1 => 
    object(stdClass)[6]
      public 'id_tag' => string '6' (length=1)
      public 'tag' => string 'tag 7' (length=5)

I'm trying to extract the values of the array 1 that do not appear in the array 2:

function foo($tags_result, $post_tags_result){
    return $tags_result->id_tag != $post_tags_result->id_tag;
}

$difference_tags = array_udiff($tags_result, $post_tags_result, 'foo');

But the result return a common value: tag 1. I expect just tag 4 and tag 9.

    array (size=3)
  0 => 
    object(stdClass)[8]
      public 'id_tag' => string '2' (length=1)
      public 'tag' => string 'tag 1' (length=5)
  1 => 
    object(stdClass)[9]
      public 'id_tag' => string '5' (length=1)
      public 'tag' => string 'tag 4' (length=5)
  3 => 
    object(stdClass)[11]
      public 'id_tag' => string '7' (length=1)
      public 'tag' => string 'tag 9' (length=5)

Upvotes: 4

Views: 1582

Answers (2)

fjcero
fjcero

Reputation: 175

From the manual:

The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

So, instead of a Boolean comparison you should do a diff to delete equal items. Since you are comparing numeric values, you should do something like:

$ php -a

php > $a = [['id'=>1],['id'=>2],['id'=>3],['id'=>4]];
php > $b = [['id'=>1],['id'=>4]];
php > $c = array_udiff($a, $b, function($a, $b){ 
               return $a['id'] - $b['id']; 
           });
php > print_r($c);
Array
(
    [1] => Array
        (
            [id] => 2
        )

    [2] => Array
        (
            [id] => 3
        )

)

In your case:

$difference_tags = array_udiff($tags_result, $post_tags_result, function(($a1, $a2){
    return $a1->id_tag - $q2->id_tag;
}));

Upvotes: 0

Kevin
Kevin

Reputation: 41873

As an alternative, you could gather all the tags that needed to be excluded first. Then after that you could now filter it thru array_filter and get the desired result. Rough example:

$tags = array();
foreach($post_tags_result as $t) {
    $tags[] = $t->tag; // gather all tags
}
// filter array using gathered tags
$result = array_filter($tags_result, function($v) use($tags){
    return !in_array($v->tag, $tags);
});

Sample Output

Upvotes: 4

Related Questions