PHP瓜分两个数组的相同元素和不同元素的两种方法

PHP分割两个数组的相同元素和不同元素的两种方法

一、举例说明

例如有两个数组A和B(当然这个A和B也可以是key=>value形式)
A = array('tt','cc','dd','mm')
B = array('ad','tt','cc','qq')
希望得到的结果是:
sameArr = array('tt','cc')
A = array('dd','mm')
B = array('ad','qq')

二、解决方案

2.1、方法一:for循环取出数据

1、for循环一个A数组;
2、使用array_search判断元素是否存在B数组中;
3、存在后unset A和B中的该元素;
4、将该相同元素添加到sameArr数组中
具体代码:
  1.  
  2. <?php
  3. $A = array('tt','cc','dd','mm');
  4. $B = array('ad','tt','cc','qq');
  5. $sameArr = array();
  6. for($i=0; $i<count($A); $i++){
  7.         $pos = array_search($A[$i], $B);
  8.         if($pos>0){
  9.                         $sameArr[] = $A[$i];
  10.                 unset($A[$i]);
  11.                 unset($B[$pos]);
  12.         }      
  13. }
  14. var_dump($sameArr, $A, $B);

key value数组形式和此类似,只需要将for循环替换为foreach循环即可,下面看一下运行结果:
PHP瓜分两个数组的相同元素和不同元素的两种方法
PHP瓜分两个数组的相同元素和不同元素的两种方法
返回结果是我们预期的结果。

2.2、方案二:利用PHP内置函数array_diff和array_intersect

同样也可以使用array_diff分割,获取在A中而不在B中的元素或者在B中而不在A中的元素,但是无法获取相同元素,要获取相同元素的话,需要使用。array_intersect函数来获取,方法如下:
  1. <?php
  2. $sameArr = array_intersect($A, $B);
  3. $diffA = array_diff($A, $B);
  4. $diffB = array_diff($B, $A);
  5. var_dump($sameArr, $diffA, $diffB);

返回结果是:
PHP瓜分两个数组的相同元素和不同元素的两种方法
PHP瓜分两个数组的相同元素和不同元素的两种方法
也是正确的,预期结果。

三、方案对比

  既然两种方案都能够满足我们现有的需求,那么接下来我们就来分析两种方法区别,以及哪种方法更优。
函数大小在千数级别时两者的效率是差不多的代码如下:
使用array_search和for循环执行
  1. <?php
  2. /*$A = array('tt','cc','dd','mm');
  3. $B = array('ad','tt','cc','qq');*/
  4.  
  5. for($i=0; $i<1000; $i++){
  6.         if($i%53 == 0){
  7.                 $A[] = 'B_' . $i;
  8.         } else {
  9.                 $A[] = 'A_' . $i;
  10.         }
  11. }
  12.  
  13. for($i=0; $i<1000; $i++){
  14.         if($i%73 == 0){
  15.                 $B[] = 'A_' . $i;
  16.         } else {
  17.                 $B[] = 'B_' . $i;
  18.         }
  19. }
  20. runtime();
  21. $sameArr = array();
  22. for($i=0; $i<count($A); $i++){
  23.         $pos = array_search($A[$i], $B);
  24.         if($pos>0){
  25.                         $sameArr[] = $A[$i];
  26.                 unset($A[$i]);
  27.                 unset($B[$pos]);
  28.         }      
  29. }
  30. //var_dump($sameArr, $A, $B);
  31. runtime('end');
  32.  
  33. function runtime($mod='')    
  34. {    
  35.     static $first; //首次运行时间    
  36.     static $prev; //上次时间    
  37.     static $str;    //输出字符串    
  38.     $time = explode(' ', microtime());    
  39.     $curr = $time[1] . substr($time[0], 1, 7); // 1212466268.034119形式    
  40.     //首次    
  41.     if(!$first) {    
  42.         $prev = $first = $curr+0;    
  43.         //$str .= '开始:'.$first.'秒<br/>';    
  44.     }else if($mod == 'end'){    
  45.         $str .= '本次: '.intval(($curr - $prev) * 100000)/100000 . '<br/>';    
  46.         //$str .= '结束: '.$curr.'秒<br/>';    
  47.         $str .= '总运行时间:'.intval(($curr - $first) * 100000)/100000 . '<br/>';    
  48.         echo $str;    
  49.     }else{    
  50.         $str .= '本次: '.intval(($curr - $prev) * 100000)/100000 . '<br/>';    
  51.         $prev = $curr;    
  52.     }    
  53. }
使用PHP的内置函数:
  1. <?php
  2. /*$A = array('tt','cc','dd','mm','da','dv','dc','de','df');
  3. $B = array('ad','tt','cc','qq');*/
  4.  
  5. for($i=0; $i<10000; $i++){
  6.         if($i%53 == 0){
  7.                 $A[] = 'B_' . $i;
  8.         } else {
  9.                 $A[] = 'A_' . $i;
  10.         }
  11. }
  12.  
  13. for($i=0; $i<10000; $i++){
  14.         if($i%73 == 0){
  15.                 $B[] = 'A_' . $i;
  16.         } else {
  17.                 $B[] = 'B_' . $i;
  18.         }
  19. }
  20.  
  21. runtime();
  22. $sameArr = array_intersect($A, $B);
  23. $diffA = array_diff($A, $B);
  24. $diffB = array_diff($B, $A);
  25. //var_dump($sameArr, $diffA, $diffB);
  26. runtime('end');
  27.  
  28. function runtime($mod='')    
  29. {    
  30.     static $first; //首次运行时间    
  31.     static $prev; //上次时间    
  32.     static $str;    //输出字符串    
  33.     $time = explode(' ', microtime());    
  34.     $curr = $time[1] . substr($time[0], 1, 7); // 1212466268.034119形式    
  35.     //首次    
  36.     if(!$first) {    
  37.         $prev = $first = $curr+0;    
  38.         //$str .= '开始:'.$first.'秒<br/>';    
  39.     }else if($mod == 'end'){    
  40.         $str .= '本次: '.intval(($curr - $prev) * 100000)/100000 . '<br/>';    
  41.         //$str .= '结束: '.$curr.'秒<br/>';    
  42.         $str .= '总运行时间:'.intval(($curr - $first) * 100000)/100000 . '<br/>';    
  43.         echo $str;    
  44.     }else{    
  45.         $str .= '本次: '.intval(($curr - $prev) * 100000)/100000 . '<br/>';    
  46.         $prev = $curr;    
  47.     }    
  48. }
对比两者执行时间都是在0.002-0.006之间,相差不是很大。

而当我们的函数级别上升到万级别以上时,对比就非常明显了,第一种方法耗时为
本次: 2.63339
总运行时间:2.63339
大概在2.6秒钟,而使用第二种内置函数方法时,
本次: 0.03148
总运行时间:0.03148
耗时依然在0.002-0.006之间,当我面将数组级别上升到十万时,时间也在0.3-0.4之间徘徊。

可以看出大数组情况下最好使用PHP的内置函数,尽量减少for的循环调用。