百科狗-知识改变命运!
--

array_diff() - 计算数组的差集 - php 数组函数

百变鹏仔1年前 (2023-11-21)阅读数 22#技术干货
文章标签数组

array_diff()

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

计算数组的差集

说明

array_diff(array $array1,array $array2[,array $...]): array

对比$array1和其他一个或者多个数组,返回在$array1中但是不在其他 array 里的值。

参数

$array1

要被对比的数组

$array2

array_diff() - 计算数组的差集 - php 数组函数

和这个数组进行比较

更多相比较的数组

返回值

返回一个数组,该数组包括了所有在$array1中但是不在任何其它参数数组中的值。注意键名保留不变。

范例

Example #1array_diff()例子

在$array1中多次出现的值一样处理,输出结果为:

Array
(
    [1] => blue
)

注释

Note:

两个单元仅在(string)$elem1 ===(string)$elem2时被认为是相同的。也就是说,当字符串的表达是一样的时候。Note:

注意本函数只检查了多维数组中的一维。当然可以用array_diff($array1[0],$array2[0]);检查更深的维度。

参见

  • array_diff_assoc() 带索引检查计算数组的差集
  • array_intersect() 计算数组的交集
  • array_intersect_assoc() 带索引检查计算数组的交集
Again, the function's description is misleading right now. I sought a function, which (mathematically) computes A - B, or, written differently, A \ B. Or, again in other words, suppose 
A := {a1, ..., an} and B:= {a1, b1, ... , bm}
=> array_diff(A,B) = {a2, ..., an}
array_diff(A,B) returns all elements from A, which are not elements of B (= A without B).
You should include this in the documentation more precisely, I think.
array_diff provides a handy way of deleting array elements by their value, without having to unset it by key, through a lengthy foreach loop and then having to rekey the array. 
If you just need to know if two arrays' values are exactly the same (regardless of keys and order), then instead of using array_diff, this is a simple method:

The function returns true only if the two arrays contain the same number of values and each value in one array has an exact duplicate in the other array. Everything else will return false.
my alternative method for evaluating if two arrays contain (all) identical values:

may be slightly faster (10-20%) than this array_diff method:

but only when the two arrays contain the same number of values and then only in some cases. Otherwise the latter method will be radically faster due to the use of a count() test before the array_diff().
Also, if the two arrays contain a different number of values, then which method is faster will depend on whether both arrays need to be sorted or not. Two times sort() is a bit slower than one time array_diff(), but if one of the arrays have already been sorted, then you only have to sort the other array and this will be almost twice as fast as array_diff().
Basically: 2 x sort() is slower than 1 x array_diff() is slower than 1 x sort().
I just came upon a really good use for array_diff(). When reading a dir(opendir;readdir), I _rarely_ want "." or ".." to be in the array of files I'm creating. Here's a simple way to remove them:

S
If you want a simple way to show values that are in either array, but not both, you can use this:

If you want to account for keys, use array_diff_assoc() instead; and if you want to remove empty values, use array_filter().
Hello guys,
I´ve been looking for a array_diff that works with recursive arrays, I´ve tried the ottodenn at gmail dot com function but to my case it doesn´t worked as expected, so I made my own. I´ve haven´t tested this extensively, but I´ll explain my scenario, and this works great at that case :D
We got 2 arrays like these:

As array_diff, this function returns all the items that is in aArray1 and IS NOT at aArray2, so the result we should expect is:

Ok, now some comments about this function:
 - Different from the PHP array_diff, this function DON´T uses the === operator, but the ==, so 0 is equal to '0' or false, but this can be changed with no impacts.
 - This function checks the keys of the arrays, array_diff only compares the values.
I realy hopes that this could help some1 as I´ve been helped a lot with some users experiences. (Just please double check if it would work for your case, as I sad I just tested to a scenario like the one I exposed) 
Resubmitting... the update for takes into account comparison issues 
Computes the difference of all the arrays 
The fact that it will use the string representation causes alot of problems with php 5.4.
When you will have an array inside your elements, it will throw a notice error.
It will throw huge amounts of notices depending on how many items you have.
The same problem you will notice when checking with objects inside your array. It will cause catchable fatal errors.
This is also the case in php 5.3
I'm going to send a bug report, because I think php should handle this.
I always wanted something like this to avoid listing all the files and folders you want to exclude in a project directory.
function array_preg_diff($a, $p) {
  foreach ($a as $i => $v)
    if (preg_match($p, $v))
      unset($a[$i]);
  return $a;
}
$relevantFiles = array_preg_diff(scandir('somedir'), '/^\./');
instead of 
$relevantFiles = array_diff(scandir('somedir'), array('.', '..', '.idea', '.project));
For case-insensitive array_diff use:
$result = array_udiff($array1, $array2, 'strcasecmp');
(Found on stackoverflow)
The difference is made only on the first level. If you want compare 2 arrays, you can use the code available at https://gist.github.com/wrey75/c631f6fe9c975354aec7 (including a class with an function to patch the array)
Here the basic function:
function my_array_diff($arr1, $arr2) {
    $diff = array();
    
    // Check the similarities
    foreach( $arr1 as $k1=>$v1 ){
      if( isset( $arr2[$k1]) ){
        $v2 = $arr2[$k1];
        if( is_array($v1) && is_array($v2) ){
          // 2 arrays: just go further...
          // .. and explain it's an update!
          $changes = self::diff($v1, $v2);
          if( count($changes) > 0 ){
            // If we have no change, simply ignore
            $diff[$k1] = array('upd' => $changes);
          }
          unset($arr2[$k1]); // don't forget
        }
        else if( $v2 === $v1 ){
          // unset the value on the second array
          // for the "surplus"
          unset( $arr2[$k1] );
        }
        else {
          // Don't mind if arrays or not.
          $diff[$k1] = array( 'old' => $v1, 'new'=>$v2 );
          unset( $arr2[$k1] );
        }
      }
      else {
        // remove information
        $diff[$k1] = array( 'old' => $v1 ); 
      }
    }
    
    // Now, check for new stuff in $arr2
    reset( $arr2 ); // Don't argue it's unnecessary (even I believe you)
    foreach( $arr2 as $k=>$v ){
      // OK, it is quite stupid my friend
      $diff[$k] = array( 'new' => $v );
    }
    return $diff;
  }
There is more fast implementation of array_diff, but with some limitations. If you need compare two arrays of integers or strings you can use such function:
  public static function arrayDiffEmulation($arrayFrom, $arrayAgainst)
  {
    $arrayAgainst = array_flip($arrayAgainst);
    
    foreach ($arrayFrom as $key => $value) {
      if(isset($arrayAgainst[$value])) {
        unset($arrayFrom[$key]);
      }
    }
    
    return $arrayFrom;
  }
It is ~10x faster than array_diff
php > $t = microtime(true);$a = range(0,25000); $b = range(15000,500000); $c = array_diff($a, $b);echo microtime(true) - $t;
4.4335179328918
php > $t = microtime(true);$a = range(0,25000); $b = range(15000,500000); $c = arrayDiffEmulation($a, $b);echo microtime(true) - $t;
0.37219095230103
This function comes in handy if we want to compare two array values only
For example we want to make a quick check on some required $_POST parameters:
function required_array($required_array_values, $dynamic_array_values){
 return (count(array_diff(
      $required_array_values,
      $dynamic_array_values
     )) > 0) ? false : true;
}
// we expect $_POST['change_password'][new, old, repeat]
$required_params = required_array(
    array('old','new','repeat'),
    array_keys($_POST['change_password'])
   );
if( !$requred_params ){
 die('error: all parameters are required!');
}else{
 echo 'good to go';
}
$c is then equivalent to array('c' => 'catty', 6 => 11, 'n' => 'nutty')
Csaba Gabor from New York
Here is a few functions to do a fast diff between two arrays in a few lines.
You can use it with other functions described in the function array_merge : array_merge_replace from an other user, and two functions using it : array_merge_diff and array_merge_diff_reverse.
Note that the keys are preserved! 
Hi!
I tried hard to find a solution to a problem I'm going to explain here, and after have read all the array functions and possibilities, I had to create what I think should exist on next PHP releases.
What I needed, it's some kind of Difference, but working with two arrays and modifying them at time, not returning an array as a result with the diference itself.
So, as an example:
A = 1,2,3
B = 2,3,4
should NOT be:
C = 1,4
but:
A = 1
B = 4
so basically, I wanted to delete coincidences on both arrays.
Now, I've some actions to do, and I know wich one I've to do with the values from one array or another.
With the normal DIFF I can't, because if I've an array like C=1,4, I dont know if I've to do the Action_A with 1 or with 4, but I really know that everything in A, will go to the Action_A and everithing in B, will go to Action_B. So same happens with 4, don't know wich action to apply...
So I created this:

This cute, works by reference, and modifies the arrays deleting coincidences on both, and leaving intact the non coincidences.
So a call to this will be somethin' like:

And HERE, I'll have my arrays as I wanted:
$original = 1
$new = 4
Now, why I use it precisely?
Imagine you've some "Events" and some users you select when create the event, can "see" this event you create. So you "share" the event with some users. Ok?
Imagine you created and Event_A, and shared with users 1,2,3.
Now you want to modify the event, and you decide to modify the users to share it. Imagine you change it to users 2,3,4.
(numbers are users ID).
So you can manage when you are going to modify, to have an array with the IDs in DDBB ($original), and then, have another array with ID's corresponding to the users to share after modifying ($new). Wich ones you've to DELETE from DDBB, and wich ones do you've to INSERT?
If you do a simple difference or somehow, you get somethin' like C=1,4.
You have no clue on wich one you've to insert or delete.
But on this way, you can know it, and that's why:
- What keeps on $original, it's somethin not existing in $new at the beggining. So you know that all what you've inside $original, have to be deleted from DDBB because what you did in the modifying process, it's to unselect those users keeping in $original.
- What keeps on $new, it's something not existing in $original at the beggining. Wich means that in the modifying process you added some new users. And those have to be inserted in DDBB. So, everything keeping inside $new, have to be inserted in the DDBB.
Conclusion:
- Remaining in $original --> delete from DB.
- Remaining in $new --> insert into DB.
And that's all!
I hope you find it useful, and I encourage PHP "makers", to add in a not distant future, somethin' like this one natively, because I'm shure that I'm not the first one needing something like this.
Best regards all,
Light.
From the page:
Note: Please note that this function only checks one dimension of a n-dimensional array. Of course you can check deeper dimensions by using array_diff($array1[0], $array2[0]);
I've found a way to bypass that. I had 2 arrays made of arrays.
I wanted to extract from the first array all the arrays not found in the second array. So I used the serialize() function: 
After spending half an hour scratching my head wondering why this function wasn't working I realised I had the arguments the wrong way round!
I needed to remove the contents of $array1 from $array2 so I tried:

WRONG!! A quick swap around and things worked smoothly...

Hope this saves someone a bit of bother
A simple multidimentional key aware array_diff function.
  

This function meets my immidiate needs but I'm shure it can be improved.
The description is wrong, array_diff() returns an array consisting of all elements in $array1 that are not in $array2. The example shows this.
Thats how it works on my php anyway.
Here's a little wrapper for array_diff - I found myself needing to iterate through the edited array, and I didn't need to original keys for anything. 
An earlier comment suggested using array_merge() to reindex the array. While this will work, array_values() is about 30-40% faster and accomplishes the same task.
Based on one lad's code, I created following function for creating something like HTML diff. I hope it will be useful. 
One common caveat of this function is that if the arrays match, an empty array is return, not a strict boolean. E.g.: 
A small thing that caused me trouble today, wich I don't see listed on this page is that array_diff keeps the placing for the uniqe values, and removes the duplicated. This gives us empty fields in the array, wich caused me a lot of trouble. The solutions was simply to use array_merge() around the array_diff.
For example: 
$array1 = array('blue', 'red', 'green');
$array2 = array('red');
array_diff($array1, $array2);
Will give us:
------
Array
(
  [0] => red
  [1] => 
  [2] => green
)
But if we use:
array_merge(array_diff($array1, $array2));
We will get:
------
Array
(
  [0] => red
  [1] => green
)
Note that array_diff is not equivalent to 

since it is a set-theoretical complement as in 
http://en.wikipedia.org/wiki/Complement_(set_theory)
As touched on in kitchin's comment of 19-Jun-2007 03:49 and nilsandre at gmx dot de's comment of 17-Jul-2007 10:45, array_diff's behavior may be counter-intuitive if you aren't thinking in terms of set theory. 
array_diff() returns a *mathematical* difference (a.k.a. subtraction) of elements in array A that are in array B and *not* what elements are different between the arrays (i.e. those that elements that are in either A or B but aren't in both A and B).
Drawing one of those Ven diagrams or Euler diagrams may help with visualization...
As far as a function for returning what you may be expecting, here's one: 
To anybody wanting a double-sided array_diff - mentioned by rudigier at noxx dot at. Remember, array_diff gives you everything in the first array that isn't in the subsequent arrays. 
$array1=array('blue','red','green');
$array2=array('blue','yellow','green');
array_merge(array_diff($array1, $array2),array_diff($array2, $array1));
Result
------
Array
(
  [0] => red
  [1] => yellow
)
If duplicate value comes in the first array, that will be also included. See in the output "blue" comes twice.

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)