• php内置函数分析之array_chunk()


     1 PHP_FUNCTION(array_chunk)
     2 {
     3     int argc = ZEND_NUM_ARGS(), num_in;
     4     zend_long size, current = 0;
     5     zend_string *str_key;
     6     zend_ulong num_key;
     7     zend_bool preserve_keys = 0;
     8     zval *input = NULL;
     9     zval chunk;
    10     zval *entry;
    11 
    12     if (zend_parse_parameters(argc, "al|b", &input, &size, &preserve_keys) == FAILURE) {
    13         return;
    14     }
    15     /* Do bounds checking for size parameter. */
    16     /* 如果 size 小于 1,会抛出一个 E_WARNING 错误并返回 NULL。 */
    17     if (size < 1) {
    18         php_error_docref(NULL, E_WARNING, "Size parameter expected to be greater than 0");
    19         return;
    20     }
    21 
    22     /* 原数组大小 */
    23     num_in = zend_hash_num_elements(Z_ARRVAL_P(input));
    24 
    25     /* 1 <= size <= num_in */
    26     if (size > num_in) {
    27         size = num_in > 0 ? num_in : 1;
    28     }
    29     
    30     /* 初始化返回值 ((num_in - 1) / size) + 1)个元素 */
    31     array_init_size(return_value, (uint32_t)(((num_in - 1) / size) + 1));
    32 
    33     // 设置(zval).u1.type_info = IS_UNDEF
    34     // chunk保存分块后的每个数组
    35     ZVAL_UNDEF(&chunk);
    36 
    37     ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, str_key, entry) {
    38         /* If new chunk, create and initialize it. */
    39         // 类型位IS_UNDEF表明,这个chunk是一个新的分块
    40         if (Z_TYPE(chunk) == IS_UNDEF) {
    41             // 初始化chunk数组,大小为size
    42             array_init_size(&chunk, (uint32_t)size);
    43         }
    44 
    45         /* Add entry to the chunk, preserving keys if necessary. */
    46         // 是否保存原数组中的键名
    47         if (preserve_keys) {
    48             if (str_key) {
    49                 entry = zend_hash_update(Z_ARRVAL(chunk), str_key, entry);
    50             } else {
    51                 entry = zend_hash_index_update(Z_ARRVAL(chunk), num_key, entry);
    52             }
    53         } else { // 不保存原数组中的键名,重新索引
    54             // 数组元素插入chunk
    55             entry = zend_hash_next_index_insert(Z_ARRVAL(chunk), entry);
    56         }
    57         zval_add_ref(entry);
    58 
    59         /* If reached the chunk size, add it to the result array, and reset the
    60          * pointer. */
    61         /*chunk大小达到size之后,将chunk加入到返回值数组return_value中,也就是一个分块完成。
    62         * 然后重置chunk为IS_UNDEF。
    63         */
    64         if (!(++current % size)) {
    65             // chunk加入到return_value
    66             add_next_index_zval(return_value, &chunk);
    67             // 重置chunk
    68             ZVAL_UNDEF(&chunk);
    69         }
    70     } ZEND_HASH_FOREACH_END(); 
    71 
    72     /* Add the final chunk if there is one. */
    73     /* 最后一个数组分块大小达不到size的时候, 将其加到return_value */
    74     if (Z_TYPE(chunk) != IS_UNDEF) {
    75         add_next_index_zval(return_value, &chunk);
    76     }
    77 }
  • 相关阅读:
    建立十字链表
    KMP算法
    魔术师发牌问题(循环链表)
    约瑟夫问题(循环链表)
    中缀表达式 转 (逆)波兰表达式
    中缀表达式求值
    迷宫问题(回溯法)
    范数
    AUC
    概率论
  • 原文地址:https://www.cnblogs.com/natian-ws/p/9142830.html
Copyright © 2020-2023  润新知