array_intersect_ukey通过自定义函数来比较键,计算数组的交集。

/*** Computes the intersection of arrays using a callback function on the keys for comparison* @link https://php.net/manual/en/function.array-intersect-ukey.php* @param array $array1 <p>* Initial array for comparison of the arrays.* </p>* @param array $array2 <p>* First array to compare keys against.* </p>* @param array $_ [optional]* @param callback $key_compare_func <p>* User supplied callback function to do the comparison.* </p>* @return array the values of array1 whose keys exist* in all the arguments.* @meta*/
function array_intersect_ukey(array $array1, array $array2, array $_ = null, $key_compare_func) { }

示例:

$array1 = ['a1' => 'aaa','b' => 'bbb','c1' => 'ccc'
];$array2 = ['a2' => 'aaa','b' => 'bbb2','c2' => 'ccc'
];$result = array_intersect_ukey($array1, $array2, function($k1, $k2){//echo $k1.'--'.$k2."\n";if ($k1 == $k2) {return 0;} elseif ($k1 < $k2)  {return -1;} else {return 1;}
});var_dump($result);//结果
//array(1) {
//  'b' =>
//  string(3) "bbb"
//}

php7.4.8 数组函数 array_intersect_ukey实现源码

PHP_FUNCTION(array_intersect_ukey)
{php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY, INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_USER);
}

php_array_intersect函数


static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_compare_type, int key_compare_type) /* {{{ */
{zval *args = NULL;HashTable *hash;int arr_argc, i, c = 0;uint32_t idx;Bucket **lists, *list, **ptrs, *p;uint32_t req_args;char *param_spec;zend_fcall_info fci1, fci2;zend_fcall_info_cache fci1_cache = empty_fcall_info_cache, fci2_cache = empty_fcall_info_cache;zend_fcall_info *fci_key = NULL, *fci_data;zend_fcall_info_cache *fci_key_cache = NULL, *fci_data_cache;PHP_ARRAY_CMP_FUNC_VARS;int (*intersect_key_compare_func)(const void *, const void *);int (*intersect_data_compare_func)(const void *, const void *);if (behavior == INTERSECT_NORMAL) {intersect_key_compare_func = php_array_key_compare_string;if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL) {/* array_intersect() */req_args = 2;param_spec = "+";intersect_data_compare_func = php_array_data_compare_string;} else if (data_compare_type == INTERSECT_COMP_DATA_USER) {/* array_uintersect() */req_args = 3;param_spec = "+f";intersect_data_compare_func = php_array_user_compare;} else {php_error_docref(NULL, E_WARNING, "data_compare_type is %d. This should never happen. Please report as a bug", data_compare_type);return;}if (ZEND_NUM_ARGS() < req_args) {php_error_docref(NULL, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());return;}if (zend_parse_parameters(ZEND_NUM_ARGS(), param_spec, &args, &arr_argc, &fci1, &fci1_cache) == FAILURE) {return;}fci_data = &fci1;fci_data_cache = &fci1_cache;} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY *//* INTERSECT_KEY is subset of INTERSECT_ASSOC. When having the former* no comparison of the data is done (part of INTERSECT_ASSOC) */if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL && key_compare_type == INTERSECT_COMP_KEY_INTERNAL) {/* array_intersect_assoc() or array_intersect_key() */req_args = 2;param_spec = "+";intersect_key_compare_func = php_array_key_compare_string;intersect_data_compare_func = php_array_data_compare_string;} else if (data_compare_type == INTERSECT_COMP_DATA_USER && key_compare_type == INTERSECT_COMP_KEY_INTERNAL) {/* array_uintersect_assoc() */req_args = 3;param_spec = "+f";intersect_key_compare_func = php_array_key_compare_string;intersect_data_compare_func = php_array_user_compare;fci_data = &fci1;fci_data_cache = &fci1_cache;} else if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL && key_compare_type == INTERSECT_COMP_KEY_USER) {/* array_intersect_uassoc() or array_intersect_ukey() */req_args = 3;param_spec = "+f";intersect_key_compare_func = php_array_user_key_compare;intersect_data_compare_func = php_array_data_compare_string;fci_key = &fci1;fci_key_cache = &fci1_cache;} else if (data_compare_type == INTERSECT_COMP_DATA_USER && key_compare_type == INTERSECT_COMP_KEY_USER) {/* array_uintersect_uassoc() */req_args = 4;param_spec = "+ff";intersect_key_compare_func = php_array_user_key_compare;intersect_data_compare_func = php_array_user_compare;fci_data = &fci1;fci_data_cache = &fci1_cache;fci_key = &fci2;fci_key_cache = &fci2_cache;} else {php_error_docref(NULL, E_WARNING, "data_compare_type is %d. key_compare_type is %d. This should never happen. Please report as a bug", data_compare_type, key_compare_type);return;}if (ZEND_NUM_ARGS() < req_args) {php_error_docref(NULL, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());return;}if (zend_parse_parameters(ZEND_NUM_ARGS(), param_spec, &args, &arr_argc, &fci1, &fci1_cache, &fci2, &fci2_cache) == FAILURE) {return;}} else {php_error_docref(NULL, E_WARNING, "behavior is %d. This should never happen. Please report as a bug", behavior);return;}PHP_ARRAY_CMP_FUNC_BACKUP();/* for each argument, create and sort list with pointers to the hash buckets */lists = (Bucket **)safe_emalloc(arr_argc, sizeof(Bucket *), 0);ptrs = (Bucket **)safe_emalloc(arr_argc, sizeof(Bucket *), 0);if (behavior == INTERSECT_NORMAL && data_compare_type == INTERSECT_COMP_DATA_USER) {BG(user_compare_fci) = *fci_data;BG(user_compare_fci_cache) = *fci_data_cache;} else if (behavior & INTERSECT_ASSOC && key_compare_type == INTERSECT_COMP_KEY_USER) {BG(user_compare_fci) = *fci_key;BG(user_compare_fci_cache) = *fci_key_cache;}for (i = 0; i < arr_argc; i++) {if (Z_TYPE(args[i]) != IS_ARRAY) {php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));arr_argc = i; /* only free up to i - 1 */goto out;}hash = Z_ARRVAL(args[i]);list = (Bucket *) pemalloc((hash->nNumOfElements + 1) * sizeof(Bucket), GC_FLAGS(hash) & IS_ARRAY_PERSISTENT);lists[i] = list;ptrs[i] = list;for (idx = 0; idx < hash->nNumUsed; idx++) {p = hash->arData + idx;if (Z_TYPE(p->val) == IS_UNDEF) continue;*list++ = *p;}ZVAL_UNDEF(&list->val);if (hash->nNumOfElements > 1) {if (behavior == INTERSECT_NORMAL) {zend_sort((void *) lists[i], hash->nNumOfElements,sizeof(Bucket), intersect_data_compare_func, (swap_func_t)zend_hash_bucket_swap);} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY */zend_sort((void *) lists[i], hash->nNumOfElements,sizeof(Bucket), intersect_key_compare_func, (swap_func_t)zend_hash_bucket_swap);}}}/* copy the argument array */RETVAL_ARR(zend_array_dup(Z_ARRVAL(args[0])));/* go through the lists and look for common values */while (Z_TYPE(ptrs[0]->val) != IS_UNDEF) {if ((behavior & INTERSECT_ASSOC) /* triggered also when INTERSECT_KEY */&& key_compare_type == INTERSECT_COMP_KEY_USER) {BG(user_compare_fci) = *fci_key;BG(user_compare_fci_cache) = *fci_key_cache;}for (i = 1; i < arr_argc; i++) {if (behavior & INTERSECT_NORMAL) {while (Z_TYPE(ptrs[i]->val) != IS_UNDEF && (0 < (c = intersect_data_compare_func(ptrs[0], ptrs[i])))) {ptrs[i]++;}} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY */while (Z_TYPE(ptrs[i]->val) != IS_UNDEF && (0 < (c = intersect_key_compare_func(ptrs[0], ptrs[i])))) {ptrs[i]++;}if ((!c && Z_TYPE(ptrs[i]->val) != IS_UNDEF) && (behavior == INTERSECT_ASSOC)) { /* only when INTERSECT_ASSOC *//* this means that ptrs[i] is not NULL so we can compare* and "c==0" is from last operation* in this branch of code we enter only when INTERSECT_ASSOC* since when we have INTERSECT_KEY compare of data is not wanted. */if (data_compare_type == INTERSECT_COMP_DATA_USER) {BG(user_compare_fci) = *fci_data;BG(user_compare_fci_cache) = *fci_data_cache;}if (intersect_data_compare_func(ptrs[0], ptrs[i]) != 0) {c = 1;if (key_compare_type == INTERSECT_COMP_KEY_USER) {BG(user_compare_fci) = *fci_key;BG(user_compare_fci_cache) = *fci_key_cache;/* When KEY_USER, the last parameter is always the callback */}/* we are going to the break */} else {/* continue looping */}}}if (Z_TYPE(ptrs[i]->val) == IS_UNDEF) {/* delete any values corresponding to remains of ptrs[0] *//* and exit because they do not present in at least one of *//* the other arguments */for (;;) {p = ptrs[0]++;if (Z_TYPE(p->val) == IS_UNDEF) {goto out;}if (p->key == NULL) {zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);} else {zend_hash_del(Z_ARRVAL_P(return_value), p->key);}}}if (c) /* here we get if not all are equal */break;ptrs[i]++;}if (c) {/* Value of ptrs[0] not in all arguments, delete all entries *//* with value < value of ptrs[i] */for (;;) {p = ptrs[0];if (p->key == NULL) {zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);} else {zend_hash_del(Z_ARRVAL_P(return_value), p->key);}if (Z_TYPE((++ptrs[0])->val) == IS_UNDEF) {goto out;}if (behavior == INTERSECT_NORMAL) {if (0 <= intersect_data_compare_func(ptrs[0], ptrs[i])) {break;}} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY *//* no need of looping because indexes are unique */break;}}} else {/* ptrs[0] is present in all the arguments *//* Skip all entries with same value as ptrs[0] */for (;;) {if (Z_TYPE((++ptrs[0])->val) == IS_UNDEF) {goto out;}if (behavior == INTERSECT_NORMAL) {if (intersect_data_compare_func(ptrs[0] - 1, ptrs[0])) {break;}} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY *//* no need of looping because indexes are unique */break;}}}}
out:for (i = 0; i < arr_argc; i++) {hash = Z_ARRVAL(args[i]);pefree(lists[i], GC_FLAGS(hash) & IS_ARRAY_PERSISTENT);}PHP_ARRAY_CMP_FUNC_RESTORE();efree(ptrs);efree(lists);
}

php_array_user_key_compare函数

static int php_array_user_key_compare(const void *a, const void *b) /* {{{ */
{Bucket *f;Bucket *s;zval args[2];zval retval;zend_long result;f = (Bucket *) a;s = (Bucket *) b;if (f->key == NULL) {ZVAL_LONG(&args[0], f->h);} else {ZVAL_STR_COPY(&args[0], f->key);}if (s->key == NULL) {ZVAL_LONG(&args[1], s->h);} else {ZVAL_STR_COPY(&args[1], s->key);}BG(user_compare_fci).param_count = 2;BG(user_compare_fci).params = args;BG(user_compare_fci).retval = &retval;BG(user_compare_fci).no_separation = 0;if (zend_call_function(&BG(user_compare_fci), &BG(user_compare_fci_cache)) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {result = zval_get_long(&retval);zval_ptr_dtor(&retval);} else {result = 0;}zval_ptr_dtor(&args[0]);zval_ptr_dtor(&args[1]);return ZEND_NORMALIZE_BOOL(result);
}

PHP函数array_intersect_ukey相关推荐

  1. PHP查看PECL模块包含的函数

    为什么80%的码农都做不了架构师?>>>    http://php.net/manual/zh/function.get-extension-funcs.php 查看PECL扩展 ...

  2. php新增数组函数,php操作数组函数

    整理了一份PHP开发中数组操作大全,包含有数组操作的基本函数.数组的分段和填充.数组与栈.数组与列队.回调函数.排序.计算.其他的数组函数等. 一.数组操作的基本函数 数组的键名和值 array_va ...

  3. PHP 数组函数分类和整理

    这几天工作之余整理和分类了PHP 中常用的数组相关的函数.如有错误和遗漏,请留言指正! 数组函数整理 创建数组函数 array array ([ mixed $... ] ):创建数组的语言结构 ar ...

  4. php数组函数(分类基本数组函数,栈函数,队列)

    php数组函数(分类基本数组函数,栈函数,队列函数) 一.总结 1.常用数组函数 函数 描述 array() 创建数组. array_combine() 通过合并两个数组来创建一个新数组. array ...

  5. PHP array_count_values() 函数用于统计数组中所有值出现的次数。

    定义和用法 array_count_values() 函数用于统计数组中所有值出现的次数. 本函数返回一个数组,其元素的键名是原数组的值,键值是该值在原数组中出现的次数. 语法 array_count ...

  6. php多维数组交集,求数组差/交集函数-php数组函数(二)

    求数组差集函数 函数只检查了多维数组中的一维.可以用 array_diff($array1[0], $array2[0]) 检查更深的维度. u:自定义函数比较,a(association):同时比较 ...

  7. php array =,PHP Array 函数

    PHP Array 函数 PHP Array 函数 ## PHP Array 简介 PHP Array 函数允许您访问并操作数组. 支持简单的数组和多维数组. ## 安装 PHP Array 函数是 ...

  8. php中文切齿,PHP 各种函数

    usleep() 函数延迟代码执行若干微秒. unpack() 函数从二进制字符串对数据进行解包. uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID. time_sleep_unti ...

  9. php array 数组函数,php array数组函数

    array():创建数组 array_change_key_case():返回其键名均为大写或小写的数组 array_chunk():把一个数组分割为新的数组块 array_combine():创建一 ...

  10. php end array_value,PHP常用处理数组函数

    一.数组的一些关于键名和值的基础操作函数 1.获取数组所有的键或值:array_keys() array_values() $array=['a'=>'A','b'=>'B',4,&quo ...

最新文章

  1. 超越谷歌BERT!依图推出预训练语言理解模型ConvBERT,入选NeurIPS 2020
  2. lucene 索引流程整理笔记
  3. 云炬Android开发笔记 6启动图功能开发与封装
  4. 常见算法的python实现(Github标星75.5k+)
  5. 前端开发利器webStorm 3.0配置使用
  6. leetcode讲解--559. Maximum Depth of N-ary Tree
  7. UDT协议实现分析——UDT Socket的创建
  8. Good Bye 2018 (A~F, H)
  9. 环境搭建:mobaxterm连接本地虚拟机
  10. phpnow mysql_PHPNOW中如何建立MYSQL数据库连接?
  11. FLV无损转换MP4
  12. 可中心可边缘,云计算“罗马大路”需要什么样的超融合新基建?
  13. 人工智能学习:python实现迭代加深的深度优先搜索
  14. C语言学习day01
  15. Flutter Sliver大家族之SliverPersistentHeader()和SliverToBoxAdapter()组件(实现固定头布局)③
  16. Linux | 人生苦短,我用Vim【最受欢迎的编辑器】
  17. 需求工程:软件建模与分析 读书笔记二
  18. Pyinstaller 打包exe附带资源,运行时自动解压所需资源(图片文本音频等)
  19. Windows上本地安装MySQL数据库
  20. 中国区首发 | 规模化敏捷RTE(企业级敏捷教练/发布火车工程师)国际认证课程

热门文章

  1. SAS入门(二)---DATA步
  2. python读取海康威视摄像头价格_OpenCV+海康威视摄像头的实时读取
  3. [转]小D课堂 - 零基础入门SpringBoot2.X到实战_汇总
  4. win10电脑虚拟网络设置方法
  5. linux的acid属性,Linux_Linux下主要浏览器Acid3大测试(组图),最近浏览器大战愈演愈烈,而 - phpStudy...
  6. VGG16网络结构图及pytorch 代码实现
  7. macOS Ventura 正式版发布 苹果官方详解macOS 13 Ventura正式版
  8. 智能小车-红外循迹篇
  9. PS去除图片和PDF中的水印
  10. 对抗网络学习-FGSM对抗样本生成