[关闭]
@52fhy 2016-02-28T11:00:15.000000Z 字数 1950 阅读 861

array_intersect系列函数使用笔记

PHP


基本使用

先看下几个函数:

array_intersect — 计算数组的交集
array_intersect_assoc — 返回一个数组,该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。注意和 array_intersect() 不同的是:键名也用于比较。
array_intersect_key — 使用键名比较计算数组的交集
array_intersect_uassoc — 带索引检查计算数组的交集,用回调函数比较索引
array_intersect_ukey — 用回调函数比较键名来计算数组的交集

名字差不多,不好区分吧?

我们从array_intersect开始理解。

说明
array array_intersect ( array $array1 , array $array2 [, array $ ... ] )
array_intersect() 返回一个数组,该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。注意键名保留不变。

返回值
返回一个数组,该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。

这个函数根据输入的数组,对其键值进行比较(忽略键名),键值一样的就认为是交集。

例如

  1. $a = array(1,2,3,4);
  2. $b = array('1','2', 4, 5, 6);
  3. $res = array_intersect($a, $b);
  4. //结果是array(1,2,4)

上面例子中,就算两个数组的键名不一致,也不影响结果。

那如果想让键名也进行比较,那就用到array_intersect_assoc了。

另外一个函数array_intersect_key则只是比较键名是否相同,相同的键名则认为是交集,至于值的话取先匹配出来的数组里的:

  1. <?php
  2. $array1 = array( 'blue' => 1 , 'red' => 2 , 'green' => 3 , 'purple' => 4 );
  3. $array2 = array( 'green' => 5 , 'blue' => 6 , 'yellow' => 7 , 'cyan' => 8 );
  4. var_dump ( array_intersect_key ( $array1 , $array2 ));
  5. ?>

以上例程会输出:

  1. array(2) {
  2. ["blue"]=>int(1)
  3. ["green"]=>int(3)
  4. }

上例中可以看到只有 'blue'和 'green' 两个键名出现在两个数组中,因此被返回。此外注意 'blue' 和 'green'的值在两个数组中是不同的。但因为只检查键名,因此还是匹配。返回的值只是 array1 中的。

在 key => value 对中的两个键名仅在 (string) key2 时被认为相等。换句话说,执行的是严格类型检查,因此字符串的表达必须完全一样。

使用技巧

Using isset to achieve this, is many times faster

引自一位网友的评论。array_intersect还是比较慢的,当数据量大的时候。

  1. <?php
  2. $m = range(1,1000000);
  3. $s = [2,4,6,8,10];
  4. // Use array_intersect to return all $m values that are also in $s
  5. $tstart = microtime(true);
  6. print_r (array_intersect($m,$s));
  7. $tend = microtime(true);
  8. $time = $tend - $tstart;
  9. echo "Took $time";
  10. // Use array_flip and isset to return all $m values that are also in $s
  11. $tstart = microtime(true);
  12. $f = array_flip($s);
  13. /* $f now looks like this:
  14. (
  15. [2] => 0
  16. [4] => 1
  17. [6] => 2
  18. [8] => 3
  19. [10] => 4
  20. )
  21. */
  22. // $u will hold the intersected values
  23. $u = [];
  24. foreach ($m as $v) {
  25. if (isset($f[$v])) $u[] = $v;
  26. }
  27. print_r ($u);
  28. $tend = microtime(true);
  29. $time = $tend - $tstart;
  30. echo "Took $time";
  31. ?>

Results:

  1. Array
  2. (
  3. [1] => 2
  4. [3] => 4
  5. [5] => 6
  6. [7] => 8
  7. [9] => 10
  8. )
  9. Took 4.7170009613037
  10. (
  11. [0] => 2
  12. [1] => 4
  13. [2] => 6
  14. [3] => 8
  15. [4] => 10
  16. )
  17. Took 0.056024074554443
  18. array_intersect: 4.717
  19. array_flip+isset: 0.056

对比很明显。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注