php获取数组第一个和最后一个元素的key

2023-05-16

PHP 7.3.0之前的版本获取数组第一个和最后一个元素的key的几种方法。

$a = [
   'one' => 1,
    'two' => 2,
    'three' => 3
];

方法一

$first = reset($a);
$first_key = key($a);

$last = end($a);
$last_key = key($a);

方法二

$keys = array_keys($a);
$first = reset($keys);
$last = end($keys);

可以使用array_keys(),但是这样做的效率可能相当低。
也可以使用reset()和key(),但是这可能会改变内部数组指针。
PHP 7.3.0 加入两个函数解决这些问题了。
see https://www.php.net/manual/zh/function.array-key-last.php

  • array_key_first
  • array_key_last
    看看它们是如果实现的。源码加了一些中文注释方便理解。
    文件在 array.c : 3952
PHP_FUNCTION(array_key_first)
{
	zval *stack;    /* 传入数组 */

	ZEND_PARSE_PARAMETERS_START(1, 1)
		Z_PARAM_ARRAY(stack) 
	ZEND_PARSE_PARAMETERS_END();

	HashTable *target_hash = Z_ARRVAL_P (stack);
	HashPosition pos = 0;   //位置0
	zend_hash_get_current_key_zval_ex(target_hash, return_value, &pos); // 根据位置取数组的key
}
ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos)
{
	uint32_t idx = *pos;
	Bucket *p;

	IS_CONSISTENT(ht);
	if (idx >= ht->nNumUsed) { //检查数组位置是否下超过数组实际使用最大元素的个数
		ZVAL_NULL(key);
	} else {
		if (idx == 0) {
			idx = _zend_hash_get_first_pos(ht); // 查找第个一有效元素的位置,因为位置0的元素可能被删除。
			if (idx >= ht->nNumUsed) {
				ZVAL_NULL(key);
				return;
			}
		}
		p = ht->arData + idx; // 根据位置找到第一个元素
		if (p->key) {    // 判断是关键数组,还是索引数组
			ZVAL_STR_COPY(key, p->key); //返回关键数组key
		} else {
			ZVAL_LONG(key, p->h);   //返回索引数组key
		}
	}
}

PHP_FUNCTION(array_key_last)
{
	zval *stack;    /* 传入数组 */
	HashPosition pos; // 最后一个有效元素的位置

	ZEND_PARSE_PARAMETERS_START(1, 1)
		Z_PARAM_ARRAY(stack)
	ZEND_PARSE_PARAMETERS_END();

	HashTable *target_hash = Z_ARRVAL_P (stack);
	zend_hash_internal_pointer_end_ex(target_hash, &pos);   //获取最后一个有效元素的位置
	zend_hash_get_current_key_zval_ex(target_hash, return_value, &pos); //根据位置取数组的key
}
ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos)
{
	uint32_t idx;

	IS_CONSISTENT(ht);
	HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);

	idx = ht->nNumUsed;  // 位置等于数组实际使用最大元素的个数
	while (idx > 0) {
		idx--;       // 从后住前递减
		if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) { // 查找元素是否有效
			*pos = idx;                               
			return;
		}
	}
	*pos = ht->nNumUsed;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

php获取数组第一个和最后一个元素的key 的相关文章

随机推荐

  • C/C++空指针总结

    在C中 在C中 xff0c 使用NULL表示空指针 xff0c 实际上 xff0c NULL被定义为 xff1a define NULL void 0 其中 void 0 表示对 0 进行强制转换 xff0c 转换为一个void类型的指针
  • Windows11镜像下载及安装

    现在微软已正式推出Windows 11预览版系统 xff0c 目前最新系统版本是22000 71 xff0c 正式版可能会在10月份推出 xff0c 届时拥有正版Windows 10系统的就可以通过Windows Update工具免费在线升
  • ROS2安装及基础知识介绍

    ros介绍 ROS xff08 Robot Operating System xff09 是一个开源的机器人操作系统 xff0c ROS系统是由大量节点组成 xff0c 其中任何一个节点都可以通过发布 订阅的方式与其他节点进行通信 举个栗子
  • Ubuntu Gnome GTK程序开机启动

    启动图标准备 GTK程序 开机启动需要首先制作desktop文件 例如 myapp autostart desktop 如下 xff1a Desktop Entry Encoding 61 UTF 8 Name 61 App Comment
  • 学习记录

    最近打算用visio画个流程图 xff0c 看看会不会遇到什么坑 1 最近打算用visio画几个流程图 xff0c 遇到什么问题在记录一番 2 分析学习一下系统权限的分配 xff0c 做到可以配置权限 xff0c 灵活一些 用户 gt 角色
  • 计算机专业学生,大三了找技术岗,怎么写一份好简历?内附269份简历模板

    计算机专业学生 xff0c 大三了找技术岗 xff0c 怎么写一份好简历 xff1f 内附269份简历模板 大家好 xff0c 我是好好学习 xff0c 天天编程的博主 xff0c 一个每天在互联网上种菜和砍柴的程序员 因为疫情的影响 xf
  • Digest Authentication 摘要认证(转载)

    原文 Digest Authentication 摘要认证 weixin 34007906的博客 CSDN博客 摘要 式认证 xff08 Digest authentication xff09 是一个简单的认证机制 xff0c 最初是为HT
  • 面试问到 Promise,这样回答最完美了

    promise是什么 xff1f Promise是异步编程的一种解决方案 xff0c 比传统的回调函数和事件更合理和强大 所谓Promise xff0c 简单来说就是一个容器 xff0c 里面保存着某个未来才会结束的事情 xff08 通常是
  • Linux编译安装内核

    0 前言 Linux系统中可同时安装多个内核镜像 xff0c 启动时选其一运行即可 xff0c Ubuntu14 04安装Linux内核 介绍了通过apt get工具安装内核的方法 xff0c 本文将介绍如果由源码安装新内核 验证版本 xf
  • Ubuntu 16.04 上用RealSense ZR300跑Vins Mono

    Ubuntu 16 04 上用RealSense ZR300跑Vins Mono 这篇博客主要讲使用RealSense ZR300运行Vins Mono xff0c 主要包括 xff1a xff08 1 xff09 ROS上RealSens
  • 一文熟悉golang编写k8s应用部署工具

    背景 xff1a 在上篇文章里 xff0c 完成了一个简陋的spring cloud 43 k8s的应用系统 xff0c 那么如果手工部署的话 xff0c 那得分别打包5个服务 xff0c 打5个镜像 xff0c 然后安装5个服务 凡是麻烦
  • jdk11安装后不自动安装jre的问题

    回寝之后我又重新自己从头配置了一遍jdk11 关于jdk11安装后不自动安装jre的问题 xff1a 虽然安装jdk11之后可以运行java version查看版本 xff0c 但还是感觉很奇怪 查了一下 xff0c 现在的jdk本身也包含
  • 说说家乡的互联网-江西龙南

    刚好在CSDN查资料 xff0c 看到这个征文 xff0c 勾起年少回忆 xff0c 遂写下此文 2003年 xff0c 我刚上初一 xff0c 学校开设了微机课 xff0c 我第一次接触了互联网 十一 xff0c 二岁的孩子对新事物充满了
  • Python 内部函数修改外部变量的值报错

    今天写题时遇到了这样一个问题 xff1a UnboundLocalError local variable 39 total 39 referenced before assignment 错误出现在我试图通过内部函数修改外部变量的值 xf
  • go get xxx: disabled by GOPRIVATE/GONOPROXY解决方案

    go拉包比如go get的时候出了这个错 xff0c 资料比较少 xff1a disabled by GOPRIVATE GONOPROXY 长话短说 xff0c 解决方案 xff1a 给你的GOPROXY加上direct xff0c 注意
  • Window10系统安装V-rep教程(有百度网盘文件包)

    Window10系统安装V rep教程 64 meng 看了很多教程 xff0c 都没有找到适合Windows10的V rep安装教程及安装包 xff0c 官网上又那么慢 xff08 最近更新了篇博客 xff0c 大家需要其他版本的请移步
  • Integer和int的区别

    Integer是int的包装类 int是基本数据类型 最主要的区别就是这句 一个是基本数据类型 一个是类 但其实其中隐含的细节很多 比如 Integer的默认初始值是null xff0c 而int的默认初试值是0 Integer变量必须先实
  • 如何配置Filebeat收集日志文件

    Filebeat7 6 日志输入 filebeat inputs type log paths var log log var path2 log 您可以添加额外的 配置设置 xff08 如fields xff0c include line
  • 在 Mac 上的“照片”中删除照片或恢复删除的照片

    从图库中删除照片和视频后 xff0c 它们会放在 最近删除 相簿中并保留所显示的天数 xff0c 然后才会永久删除 您可以在该时间段结束前恢复项目 如果打开了 iCloud 照片 xff0c 您可以在 30 天内从 iCloud 恢复照片和
  • php获取数组第一个和最后一个元素的key

    PHP 7 3 0之前的版本获取数组第一个和最后一个元素的key的几种方法 span class token variable a span span class token operator 61 span span class toke