How Does Array_Diff Work

How does array_diff work?

UPDATE

  • see below for faster/better code.

  • array_diff behaviour is much better in php 5.3.4, but still ~10 times slower than Leo's function.

  • also it's worth noting that these functions are not strictly equivalent to array_diff since they don't maintain array keys, i.e. my_array_diff(x,y) == array_values(array_diff(x,y)).

/UPDATE

A better solution is to use hash maps

function my_array_diff($a, $b) {
$map = $out = array();
foreach($a as $val) $map[$val] = 1;
foreach($b as $val) if(isset($map[$val])) $map[$val] = 0;
foreach($map as $val => $ok) if($ok) $out[] = $val;
return $out;
}

$a = array('A', 'B', 'C', 'D');
$b = array('X', 'C', 'A', 'Y');

print_r(my_array_diff($a, $b)); // B, D

benchmark

function your_array_diff($arraya, $arrayb)
{
foreach ($arraya as $keya => $valuea)
{
if (in_array($valuea, $arrayb))
{
unset($arraya[$keya]);
}
}
return $arraya;
}

$a = range(1, 10000);
$b = range(5000, 15000);

shuffle($a);
shuffle($b);

$ts = microtime(true);
my_array_diff($a, $b);
printf("ME =%.4f\n", microtime(true) - $ts);

$ts = microtime(true);
your_array_diff($a, $b);
printf("YOU=%.4f\n", microtime(true) - $ts);

result

ME =0.0137
YOU=3.6282

any questions? ;)

and, just for fun,

$ts = microtime(true);
array_diff($a, $b);
printf("PHP=%.4f\n", microtime(true) - $ts);

result

ME =0.0140
YOU=3.6706
PHP=19.5980

that's incredible!

Why does PHP array_diff work this way

array_diff() looks for exact duplicates for each value of array 1 in array 2, ignoring the keys.

1 has a duplicate in array 2, e.g. under key order. That's why it's not listed as difference.

Whether or not this behavior is optimal or obvious is debatable, but that's how it works.


If you change the 1 to a 3, it will be reported, as array 2 does not contain a value 3:

    $array_1 = [
'id' => '42',
'base_id' => '23',
'role_id' => '3',
'title' => 'Manage Account',
'slug' => 'manage_account',
'parent' => '31',
'order' => '1',
'visibility' => '1'
];
$array_2 = [
'id' => '42',
'base_id' => '23',
'role_id' => '99999',
'title' => 'Manage Account',
'slug' => 'manage_account',
'parent' => '31',
'order' => '1',
'visibility' => '1'
];

var_dump(array_diff($array_1, $array_2));
// Result (unexpected)
// array (size=1)
// 'role_id' => string '3' (length=1)

If you want the keys to be taken into account, use array_diff_assoc() instead.

array_diff on array of objects

You shouldn't use array_diff to compare the arrays with objects.

To do it properly you need to use array_udiff() and you need to define what "difference" between objects means.

For example objects may be different if they have different id

function compareCars(Car $objA, Car $objB) {
return $objA->getId() <=> $objB->getId();
}

$diff = array_udiff($allCars, $busyCars, 'compareCars')

If you added for example ComparableInterface to every class that you want to compare via id with just one method getId() then you could use the benefits of polymorphism

interface ComparableInterface
{
public function getId();
}

class Car implements ComparableInterface
{
public function getId()
{
return $this->id;
}
//rest of the class source
}

function compareCars(ComparableInterface $objA, ComparableInterface $objB) {
return $objA->getId() <=> $objB->getId();
}

or even define compare() method that returns for every object if it's equal or not

interface AdvancedComparableInterface extends ComparableInterface
{
public function compare(ComparableInterface $obj);
}

class Car implements AdvancedComparableInterface
{
public function getId()
{
return $this->id;
}

public function compare(ComparableInterface $obj)
{
return $this->getId() <=> $obj->getId();
}
//rest of the class source
}

function compareCars(AdvancedComparableInterface $objA, ComparableInterface $objB) {
return $objA->compare($objB);
}

As you see you can use multiple ways of defining if the object is the same as the other one. For example the cars you could be compared by VIN

Side note:

Executing the queries in a loop is a bad idea in terms of doctrine's performance. It's be better if you make one query by passing ids of busyWeek as array to findBy method.

PHP - array_diff does not work as it supposed to

array_diff only checks for values, no checks for keys

you need to use array_diff_assoc to check along with keys

Simple array_diff not working

hope you have already found the solution, but just in case I want to point you on following.

Blockquote
I did a var_dump on both of my arrays and here is the result.
$teach_array : array(5) { [0]=> string(5) " 1 " [1]=> string(5) " 2 " [2]=> string(5) " 3 " [3]=> string(5) " 4 " [4]=> string(5) " 5 " }
$lang_array : array(2) { [0]=> string(1) "2" [1]=> string(1) "3" }

No single value from $teach_array matches any value of $lang_array.
Because there are differently formatted values, one array contains whitespaces before and after the value you want to match " 2 ".

var_dump($teach_array) => array(5) { [0]=> string(5) " 4 " ... }
var_dump($lang_array) => array(5) { [0]=> string(1) "2" ... }

I guess you have some whitespaces included. Please try again with:

$diff = array_diff(array_map('trim', $teach_array), $lang_array);

Using array_diff(), how to get difference from array2 instead of array1?

The order of arguments in array_diff() is important

Returns an array containing all the entries from array1 that are not
present in any of the other arrays

array_diff() function not showing correct result

Since your arrays are associative arrays, so you need to use array_diff_assoc:-

<?php

$a = Array(
'designation_id' =>1,
'name' => 'Y',
'fathers_name' => 'Z',
'mothers_name' => 'F',
'spouse_name' => 'd',
'gender' => 'F',
'last_achieved_degree' => 2,
'date_of_birth' => '1960-10-17',
'date_of_joining' => '1987-02-04'
);

$b =Array
(
'designation_id' => 9,
'name' => 'M',
'fathers_name' => 'N',
'mothers_name' => 'O',
'spouse_name' => '',
'gender' => 'M',
'last_achieved_degree' => 1,
'date_of_birth' => '1967-11-17',
'date_of_joining' => '2016-01-01',
);

echo "<pre/>";print_r(array_diff_assoc($a,$b));

Output:- https://3v4l.org/NKbuX

To check more descriptions and examples:- http://sg2.php.net/manual/en/function.array-diff-assoc.php

Why array_diff() not worked:- https://stackoverflow.com/a/4742438/4248328



Related Topics



Leave a reply



Submit