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

Posted danhuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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. var_dump ( $sameArr ,  $A ,  $B ) ;

key value数组形式和此类似,只需要将for循环替换为foreach循环即可,下面看一下运行结果:
返回结果是我们预期的结果。

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 ) ;

返回结果是:
也是正确的,预期结果。

三、方案对比

  既然两种方案都能够满足我们现有的需求,那么接下来我们就来分析两种方法区别,以及哪种方法更优。 函数大小在千数级别时两者的效率是差不多的代码如下: 使用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. for ( $i = 0 ;  $i < 1000 ;  $i ++ )
  13.          if ( $i % 73  ==  0 )
  14.                  $B [ ]  =  'A_'  .  $i ;
  15.            else 
  16.                  $B [ ]  =  'B_'  .  $i ;
  17.         
  18. runtime ( ) ;
  19. $sameArr  =  array ( ) ;
  20. for ( $i = 0 ;  $i < count ( $A ) ;  $i ++ )
  21.          $pos  =  array_search ( $A [ $i ] ,  $B ) ;
  22.          if ( $pos > 0 )
  23.                          $sameArr [ ]  =  $A [ $i ] ;
  24.                  unset ( $A [ $i ] ) ;
  25.                  unset ( $B [ $pos ] ) ;
  26.                
  27. //var_dump($sameArr, $A, $B);
  28. runtime ( 'end' ) ;
  29.  
  30. function runtime ( $mod = '' )    
  31.     
  32.     static  $first ;  //首次运行时间    
  33.     static  $prev ;  //上次时间    
  34.     static  $str ;     //输出字符串    
  35.      $time  =  explode ( ' ' ,  microtime ( ) ) ;    
  36.      $curr  =  $time [ 1 ]  .  substr ( $time [ 0 ] ,  1 ,  7 ) ;  // 1212466268.034119形式    
  37.      //首次    
  38.      if ( ! $first )      
  39.          $prev  =  $first  =  $curr + 0 ;    
  40.          //$str .= '开始:'.$first.'秒<br/>';    
  41.      else  if ( $mod  ==  'end' )     
  42.          $str  .=  '本次: ' . intval ( ( $curr  -  $prev )  *  100000 ) / 100000  .  '<br/>' ;    
  43.          //$str .= '结束: '.$curr.'秒<br/>';    
  44.          $str  .=  '总运行时间:' . intval ( ( $curr  -  $first )  *  100000 ) / 100000  .  '<br/>' ;    
  45.          echo  $str ;    
  46.      else     
  47.          $str  .=  '本次: ' . intval ( ( $curr  -  $prev )  *  100000 ) / 100000  .  '<br/>' ;    
  48.          $prev  =  $curr ;    
  49.          
使用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. for ( $i = 0 ;  $i < 10000 ;  $i ++ )
  13.          if ( $i % 73  ==  0 )
  14.                  $B [ ]  =  'A_'  .  $i ;
  15.            else 
  16.                  $B [ ]  =  'B_'  .  $i ;
  17.         
  18.  
  19. runtime ( ) ;
  20. $sameArr  =  array_intersect ( $A ,  $B ) ;
  21. $diffA  =  array_diff ( $A ,  $B ) ;
  22. $diffB  =  array_diff ( $B ,  $A ) ;
  23. //var_dump($sameArr, $diffA, $diffB);
  24. runtime ( 'end' ) ;
  25.  
  26. function runtime ( $mod = '' )    
  27.     
  28.     static  $first ;  //首次运行时间    
  29.     static  $prev ;  //上次时间    
  30.     static  $str ;     //输出字符串    
  31.      $time  =  explode ( ' ' ,  microtime ( ) ) ;    
  32.      $curr  =  $time [ 1 ]  .  substr ( $time [ 0 ] ,  1 ,  7 ) ;  // 1212466268.034119形式    
  33.      //首次    
  34.      if ( ! $first )      
  35.          $prev  =  $first  =  $curr + 0 ;    
  36.          //$str .= '开始:'.$first.'秒<br/>';    
  37.      else  if ( $mod  ==  'end' )     
  38.          $str  .=  '本次: ' . intval ( ( $curr  -  $prev )  *  100000 ) / 100000  .  '<br/>' ;    
  39.          //$str .= '结束: '.$curr.'秒<br/>';    
  40.          $str  .=  '总运行时间:' . intval ( ( $curr  -  $first )  *  100000 ) / 100000  .  '<br/>' ;    
  41.          echo  $str ;    
  42.      else     
  43.          $str  .=  '本次: ' . intval ( ( $curr  -  $prev )  *  100000 ) / 100000  .  '<br/>' ;    
  44.          $prev  =  $curr ;    
  45.          
对比两者执行时间都是在 0.002-0.006之间,相差不是很大。
而当我们的函数级别上升到万级别以上时,对比就非常明显了,第一种方法耗时为 本次: 2.63339
总运行时间:2.63339
大概在2.6秒钟,而使用第二种内置函数方法时, 本次: 0.03148
总运行时间:0.03148
耗时依然在0.002-0.006之间,当我面将数组级别上升到十万时,时间也在0.3-0.4之间徘徊。
可以看出大数组情况下最好使用PHP的内置函数,尽量减少for的循环调用。



以上是关于PHP分割两个数组的相同元素和不同元素的两种方法的主要内容,如果未能解决你的问题,请参考以下文章

PHP删除数组中特定元素的两种方法

破解大厂算法面试最难动态规划题:将数组分割成元素和相等的两部分

算法:元素个数为2n的数组,把数组分割为元素个数为n的两个数组,并使这两个子数组的和最接近

PHP中数组合并的两种方法及区别介绍

Java连载66-数组的两种初始化方式

小橙书阅读指南——归并排序的两种实现