2

I'm trying to use array_intersect to compare two arrays of arrays.

$start[]=array(
        'id'=>1,
        'name'=>'Up',
        'action'=>'up'
);
$start[]=array(
        'id'=>3,
        'name'=>'Down',
        'action'=>'down'
);
$start[]=array(
        'id'=>5,
        'name'=>'Left',
        'action'=>'left'
);




$end[]=array(
        'id'=>1,
        'name'=>'Up',
        'action'=>'up'
);
$end[]=array(
        'id'=>9,
        'name'=>'Up',
        'action'=>'up'
);

$result=array_intersect($start,$end);

However, I always get the notice message:

Notice: Array to string conversion in testfile.php on line xyz

And the comparison doesn't actually occur.

What is the best way to compare the two arrays without reinventing the wheel or arriving at something overly complex?

Force Flow
  • 714
  • 2
  • 14
  • 34

2 Answers2

6

The array_diff and array_intersect convert each element in the primary array in to a string for comparison. If you would like a different comparison, then you could use the callback method with the following built-in functions:

array_uintersect_assoc() - Computes the intersection of arrays with additional index check, compares data by a callback function
array_intersect_uassoc() - Computes the intersection of arrays with additional index check, compares indexes by a callback function
array_uintersect_uassoc() - Computes the intersection of arrays with additional index check, compares data and indexes by a callback functions

I found these by searching PHP.net for the function array_diff and followed the related function links. Its a great way to see alternatives for doing something.

SamA
  • 587
  • 3
  • 6
  • 1
    There is no additional index to check against. None of those functions solve the issue by themselves. What would I call back? – Force Flow Sep 25 '13 at 16:30
  • Well, if its **ALWAYS** a two-dimensional array a callback to another array compare function would work. Another, purpose-built function could be written as well. The idea is to let PHP do the iterating and just to write the compare function as dictated by the given situation. – SamA Sep 25 '13 at 16:35
  • I don't have an additional index to supply--and I'm not even sure that the index check is supposed to do. What comparison callback function would be appropriate? – Force Flow Sep 25 '13 at 16:40
  • The index checking is just another level of array compare. If its not needed, a callback that always returns "index match" would work. Here is another answer on Stack Overflow that might be of some use: http://stackoverflow.com/questions/3876435/recursive-array-diff – SamA Sep 25 '13 at 16:40
  • That's diff, not intersect. – Force Flow Sep 25 '13 at 16:41
  • I would think array_diff would work though I think the result from it may have to be reinterpreted to the format required by a callback's return value. – SamA Sep 25 '13 at 16:41
  • That seems like an overly complex approach to what seems to be a fairly simple problem. All that convoluted code just to intersect arrays? – Force Flow Sep 25 '13 at 16:44
  • The issue seems to be recursively intersecting arrays. – SamA Sep 25 '13 at 16:46
  • After messing with this for an hour, I still can't get anything to function as intended. This answer is far to vague. – Force Flow Sep 25 '13 at 17:49
  • Agh, I give up. I can't get it to work. I was trying to avoid reinventing the wheel, and here I am ending up trying to rewrite the array_intersect function from scratch. – Force Flow Sep 25 '13 at 18:29
2

Someone else elsewhere suggested array_map and serialize. I ended up coming up with this--which is certainly much easier than nesting and recursion and failing miserably in an attempt to basically rewrite the array_intersect function.

echo '<pre>';

$start[]=array(
        'id'=>1,
        'name'=>'Up',
        'action'=>'up'
);
$start[]=array(
        'id'=>3,
        'name'=>'Down',
        'action'=>'down'
);
$start[]=array(
        'id'=>5,
        'name'=>'Left',
        'action'=>'left'
);
$start[]=array(
        'id'=>2,
        'name'=>'Left',
        'action'=>'left'
);





$end[]=array(
        'name'=>'Up',
        'id'=>1,

        'action'=>'up'
);
$end[]=array(
        'id'=>8,
        'name'=>'Right',
        'action'=>'Right'
);




function serialize_array_values($arr){
    foreach($arr as $key=>$val){
        sort($val);
        $arr[$key]=serialize($val);
    }

    return $arr;
}




$result = array_map("unserialize", array_intersect(serialize_array_values($start),serialize_array_values($end)));

echo "\n\n\n";
echo var_dump($result);


echo '</pre>';
Force Flow
  • 714
  • 2
  • 14
  • 34