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
Message: Trying to Access Array Offset on Value of Type Null
Connection Reset by Peer: Mod_Fcgid: Error Reading Data from Fastcgi Server
Soapfault Exception: Could Not Connect to Host
Single Session Login in Laravel
Multi-Byte Safe Wordwrap() Function for Utf-8
Php-Sort Array Based on Another Array
Premature End of Script Headers: Index.Php, Mod_Fcgid: Read Data Timeout in 61 Seconds
Downloading a Folder Through with Ftp Using PHP
Using SQLite3 in PHP How to Count the Number of Rows in a Result Set
How to Wrap Long Lines Without Spaces in HTML
Openssl Not Working on Windows, Errors 0X02001003 0X2006D080 0X0E064002
How to Implement a Decorator in PHP
Facebook API/PHP - How to Change a User's Profile Image via Fb Graph API