[PHP源码阅读]array_slice和array_splice函数
array_slice和array_splice函数是用在取出数组的一段切片,array_splice还有用新的切片替换原删除切片位置的功能。类似javascript中的Array.prototype.splice和Array.prototype.slice方法。
我在github上有对PHP源码更详细的注解。感兴趣的可以围观一下,给个star。PHP5.4源码注解。可以通过commit记录查看已添加的注解。
array_slice
array array_slice ( array $array , int $offset [, int $length = NULL [, bool $preserve_keys = false ]] )
返回数组中指定下标offset和长度length的子数组切片。
参数说明
设第一个参数数组的长度为num_in。
offset
如果offset是正数且小于length,则返回数组会从offset开始;如果offset大于length,则不操作,直接返回。如果offset是负数,则offset = num_in+offset,如果num_in+offset == 0,则将offset设为0。
length
如果length小于0,那么会将length转为num_in - offset + length;否则,如果offset+length > array_count,则length = num_in - offset。如果处理后length还是小于0,则直接返回。
preserve_keys
默认是false,默认不保留数字键值原顺序,设为true的话会保留数组原来的数字键值顺序。
使用实例
<?php
$input = array("a", "b", "c", "d", "e");
$output = array_slice($input, 2); // returns "c", "d", and "e"
$output = array_slice($input, -2, 1); // returns "d"
$output = array_slice($input, 0, 3); // returns "a", "b", and "c"
print_r(array_slice($input, 2, -1)); // array(0 => 'c', 1 => 'd');
print_r(array_slice($input, 2, -1, true)); // array(2 => 'c', 1 => 'd');
运行步骤
处理参数:offset、length
移动指针到offset指向的位置
从offset开始,拷贝length个元素到返回数组
运行流程图如下

array_splice
array array_splice ( array &$input , int $offset [, int $length = 0 [, mixed $replacement = array() ]] )
删除input中从offset开始length个元素,如果有replacement参数的话用replacement数组替换删除掉的元素。
参数说明
array_splice函数中的offset和length参数跟array_slice函数中的用法一样。
replacement
如果这个参数设置了,那么函数将使用replacement数组来替换。
如果offset和length指定了没有任何元素需要移除,那么replacement会被插入到offset的位置。
如果replacement只有一个元素,可以不用array()去包着它。
使用示例
<?php
$input = array("red", "green", "blue", "yellow");
array_splice($input, 2);
// $input变为 array("red", "green")
$input = array("red", "green", "blue", "yellow");
array_splice($input, 1, -1);
// $input变为 array("red", "yellow")
$input = array("red", "green", "blue", "yellow");
array_splice($input, 1, count($input), "orange");
// $input变为 array("red", "orange")
$input = array("red", "green", "blue", "yellow");
array_splice($input, -1, 1, array("black", "maroon"));
// $input为 array("red", "green",
// "blue", "black", "maroon")
$input = array("red", "green", "blue", "yellow");
array_splice($input, 3, 0, "purple");
// $input为 array("red", "green",
// "blue", "purple", "yellow");
源码解读
在array_splice中,有这么一段代码:
/* Don't create the array of removed elements if it's not going
* to be used; e.g. only removing and/or replacing elements */
if (return_value_used) { // 如果有用到函数返回值则创建返回数组,否则不创建返回数组
int size = length;
/* Clamp the offset.. */
if (offset > num_in) {
offset = num_in;
} && (offset = (num_in + offset)) < ) {
offset = ;
}
/* ..and the length */
) {
size = num_in - offset + length;
} else if (((unsigned long) offset + (unsigned long) length) > (unsigned) num_in) {
size = num_in - offset;
}
/* Initialize return value */
array_init_size(return_value, size > ? size : );
rem_hash = &Z_ARRVAL_P(return_value);
}
array_splice函数返回的是被删除的切片。这段代码的意思是,如果array_splice需要返回值,那么才创建返回数组,否则不创建,以免浪费空间。这也是一个编程小技巧,仅当需要的时候才返回。比如在函数中使用$result = array_splice(...),那么return_value_used就是true。
总结
到此本文结束,在平时编程中,应当像这两个函数实现时的做法一样,将最特殊的情况先处理掉,然后再继续,以免做了多余的判断;有需要保存新变量的时候才申请新的空间,不然会造成浪费。
原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
如果本文对你有帮助,请点下推荐吧,谢谢^_^
最后再安利一下,我在github有对PHP源码更详细的注解。感兴趣的可以围观一下,给个star。PHP5.4源码注解。可以通过commit记录查看已添加的注解。
更多源码文章,欢迎访问个人主页继续查看:hoohack
[PHP源码阅读]array_slice和array_splice函数的更多相关文章
- [PHP源码阅读]explode和implode函数
explode和implode函数主要用作字符串和数组间转换的操作,比如获取一段参数后根据某个字符分割字符串,或者将一个数组的结果使用一个字符合并成一个字符串输出.在PHP中经常会用到这两个函数,因此 ...
- CI框架源码阅读笔记3 全局函数Common.php
从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...
- [PHP源码阅读]array_pop和array_shift函数
上篇文章介绍了PHP添加元素到数组的函数,那么当然有从数组中删除元素.array_pop和array_shift只从数组的头或尾删除一个元素.经过阅读源码,发现这两个函数的实现都是调用了同一个函数-- ...
- [PHP源码阅读]array_push和array_unshift函数
在PHP中,在数组中添加元素也是一种很常用的操作,分别有在数组尾部和头部添加元素,看看PHP内部是如何实现数组插入的操作. 我在github有对PHP源码更详细的注解.感兴趣的可以围观一下,给个sta ...
- [PHP源码阅读]empty和isset函数
近日被问到PHP中empty和isset函数时怎么判断变量的,刚开始我是一脸懵逼的,因为我自己也只是一知半解,为了弄懂其真正的原理,赶紧翻开源码研究研究.经过分析可发现两个函数调用的都是同一个函数,因 ...
- PHP源码阅读(一):str_split函数
注:源码版本:php5.6.33. 函数简介 str_split 原型: array str_split ( string $string [, int $split_length = 1 ] ) 说 ...
- [PHP源码阅读]strtolower和strtoupper函数
字符串的操作函数中,字符串的大小写转换也算是比较常用的函数,其底层实现也比较简单,下面来一探究竟. 我在github上有对PHP源码更详细的注解.感兴趣的可以围观一下,给个star.PHP5.4源码注 ...
- ONNX Runtime 源码阅读:Graph::SetGraphInputsOutputs() 函数
目录 前言 正文 总结 前言 为了深入理解ONNX Runtime的底层机制,本文将对 Graph::SetGraphInputsOutputs() 的代码逐行分析. 正文 首先判断Graph是否从O ...
- CI框架源码阅读笔记4 引导文件CodeIgniter.php
到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...
随机推荐
- 笔记:Binder通信机制
TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...
- MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信
MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...
- 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】
说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...
- UIViewController生命周期-完整版
一.UIViewController 的生命周期 下面带 (NSObject)的方法是NSObject提供的方法.其他的都是UIViewController 提供的方法. load (NSObje ...
- nodejs项目mysql使用sequelize支持存储emoji
nodejs项目mysql使用sequelize支持存储emoji 本篇主要记录nodejs项目阿里云mysql如何支持存储emoji表情. 因由 最近项目遇到用户在文本输入emoji进行存储的时候导 ...
- .NET面试题集锦①(Part一)
一.前言部分 文中的问题及答案多收集整理自网络,不保证100%准确,还望斟酌采纳. 1.面向对象的思想主要包括什么? 答:任何事物都可以理解为对象,其主要特征: 继承.封装.多态.特点:代码好维护,安 ...
- css样式之border-radius
border-radius 属性设置边框的园角 可能的值:像素,百分比 扩展延伸 html代码 <div></div> css代码 div { height: 200px; w ...
- NV显卡Ubuntu14.04更新软件导致登录死循环,不过可以进入tty模式
注意:此方法只适用于nv显卡的电脑! 在网上寻找各种方法无果的情况下,选择重新安装显卡驱动,成功登录进入图形界面. 一.首先需要在另外一台电脑(windows系统也可以)上下载NVIDIA相应显卡驱动 ...
- Linux虚拟化学习笔记<一>
关于虚拟化,原理的东西是非常复杂的,要想完全理解,没有足够的耐心是不不能完全学透这部分内容的.那下面我主要以资源汇总的形式把一些资料罗列出来,帮助大家快速理解虚拟化,快速使用和配置. 为什么要虚拟化: ...
- 瞬间记住Javascript中apply与call的区别
关于Javascript函数的apply与call方法的用法,网上的文章很多,我就不多话了.apply和call的作用很相似,但使用方式有区别 apply与call的第一个参数都是一个对象,这个对象就 ...