C#实现Javascript的Splice方法
最近开始学习Javascript语言,看到splice方法,以下引用其说明:该方法是一个通用删除和插入元素的方法,它可以在数组指定的位置开始删除或插入元素。其包括3个参数:第一个参数指定插入的起始位置,第二个参数指定要删除元素的个数,第三个参数开始表示插入的具体元素,方法返回被删除的元素数组。觉得此方法很不错,所以也想尝试用C#实现一个。
刚开始马上想到用扩展方法实现,如此才会跟Javascript里的用法一样。很快发现C#里的数组大小是固定的,不能修改,而Javascript里的splice方法需要动态的改变数组的大小。C#的System.Array类没有提供修改数组的方法,包括Clear()方法也仅仅是将数组中的每个元素都设置为其默认值(false,0或null);Resize()方法则是创建新数组,并将所有元素复制到新数组。最终只能以比较丑陋的Helper类的方式实现,如有高人知道更好的方式,请不吝赐教。
由于需求比较明确,所以直接写了第一个测试,即删除数组第3、第4个元素并返回被删除的元素。TDD是很好的开发方法,让你目标明确,明白自己下一步要做什么,以及知道自己是否已经达成了目标,也让你放心的去重构代码。这里不再一步步说明怎么按照TDD的要求,用最少的代码达成测试的要求,直接贴出两段测试,以说明Splice方法是怎么工作的。这也是TDD的好处之一,测试就是示例代码。
[Fact]
public void TrancateTwoElements()
{
int[] a = { , , , , , }; int[] b = ArrayHelper.Splice(ref a, , ); Assert.Equal(new int[] { , , , }, a);
Assert.Equal(new int[] { , }, b);
}
[Fact]
public void TrancateArrayAndInsertNewElements()
{
int[] a = { , , , , , }; int[] b = ArrayHelper.Splice(ref a, , , , , ); Assert.Equal(new int[] { , , , , , , }, a);
Assert.Equal(new int[] { , }, b);
}
代码的整体思路是,先新建两个数组,分别用于存放被删除元素和剩余的元素加上插入的新元素(如果有的话),然后把要删除的元素拷贝到用于保存被删除元素的数组,接着拷贝源数组删除位置前的需要保留的元素到新数组,然后把要插入的元素拷贝到新数组,最后把源数组末尾的元素拷贝到新数组。还是用代码说话会计较清楚:
public static T[] Splice<T>(ref T[] sourceArray, int sourceIndex, int length, params T[] insertedElements)
{
// 此处省略防卫语句 // 如果要截取的元素个数大于从sourceIndex开始到数组结束的元素个数
int acturalLength = (sourceIndex + length) > sourceArray.Length ? (sourceArray.Length - sourceIndex) : length;
var deletedItems = new T[acturalLength];
Array.ConstrainedCopy(sourceArray, sourceIndex, deletedItems, , acturalLength); int arrayLengthDifference = insertedElements.Length - acturalLength;
int newArrayLength = sourceArray.Length + arrayLengthDifference;
var newArray = new T[newArrayLength]; int newArrayCopyedElementsIndex = sourceIndex;
Array.Copy(sourceArray, newArray, newArrayCopyedElementsIndex); Array.ConstrainedCopy(insertedElements, , newArray, newArrayCopyedElementsIndex, insertedElements.Length);
newArrayCopyedElementsIndex += insertedElements.Length; int remainedElementsIndex = sourceIndex + acturalLength;
// 源数组末尾还有元素才进行拷贝
if (remainedElementsIndex < sourceArray.Length)
{
Array.ConstrainedCopy(sourceArray, remainedElementsIndex, newArray, newArrayCopyedElementsIndex, sourceArray.Length - remainedElementsIndex);
} sourceArray = newArray; return deletedItems;
}
完成的代码及测试请查看https://github.com/axbxcxdx/ZxbLib
通过写这段代码体会到了日常用惯了List等集合类,现在用数组去存放操作元素好像又回到C语言写代码的感觉,要注意数组下标、数组边界和数组的大小。
C#实现Javascript的Splice方法的更多相关文章
- 详解JavaScript的splice()方法
from:http://www.jquerycn.cn/a_10447 在javascript中splice()方法,是一个很强的数组方法,它有多种用法.splice()主要用途是向数组的中部插入项. ...
- 详解 JavaScript 中 splice() 方法
splice() 方法是一个比较少用的方法,但是功能确实很好,并且在我们 coding 的时候,经常有需要 splice() 方法,先介绍一下该方法. 在 JavaScript 中 splice() ...
- javascript中的splice方法介绍&示例
javascript 中的 splice 方法很强大,它可以用于插入.删除或替换数组的元素. 下面来一一介绍! 删除:用于删除元素,两个参数,第一个参数(要删除第一项的位置),第二个参数(要删除的项数 ...
- JavaScript splice() 方法
定义和用法 splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. 注释:该方法会改变原始数组. 例子 1 在本例中,我们将创建一个新数组,并向其添加一个元素: <script ...
- javascript数组Array强大的splice()方法
javascript的Array数组提供了强大的splice()方法, 用于对数组元素的增删改 1.删除-用于删除元素,两个参数,第一个参数(要删除第一项的位置),第二个参数(要删除的项数) 删除: ...
- JavaScript中的splice方法
splice方法根据传入的不同参数可分别实现删除和插入操作 使用splice(pra1,pra2,pra3)方法,需要为其提供如下参数: 1.pra1为其起始索引(即希望开始添加元素的地方) 2.pr ...
- 关于Javascript splice方法的一个坑。
w3c相关文档:http://www.w3school.com.cn/jsref/jsref_splice.asp bug:购物车计算价格的时候.加商品没问题,减商品的时候价格总是计算错误. 经排查发 ...
- Javascript:splice()方法实现对数组元素的插入、删除、替换及去重
定义和用法 splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. 注释:该方法会改变原始数组. 语法: Array.prototype.splice(index,count[,el ...
- JavaScript引用类型之Array数组之强大的splice()方法
splice()方法可以说是Array数组最强大的方法,他的用法很多,主要用法是向数组的中部插入项! 下面是它的用法: arrayObject.splice(index,howmany,element ...
随机推荐
- vector在一个循环里同时删除插入
vector<int> a; a.push_back(10); a.push_back(20); a.push_back(30); a.push_back(40); a.push_back ...
- 爬虫开发6.selenuim和phantonJs处理网页动态加载数据的爬取
selenuim和phantonJs处理网页动态加载数据的爬取阅读量: 1203 动态数据加载处理 一.图片懒加载 什么是图片懒加载? 案例分析:抓取站长素材http://sc.chinaz.com/ ...
- Kalibr installation tutorial
How to install Kalibr I was confused about installing Kalibr, but there is no even one hint in READM ...
- 【maven】---初识
前言 最近在研究自动化测试,其中的一个研究点儿就是maven,去download了一本书,看了看.下面是自己的从书中摘录的一些关于maven的概念性的东西. 内容 maven是什么? Maven是一个 ...
- JavaScript 实现用户点击图片放大
JavaScript 实现用户点击图片放大 一.契机 情况是这样的,之前推荐朋友去建站.后面他专门写了一篇文章说如何实现 "用户点击图片实现放大效果",俺就好好 "拜读& ...
- Laravel 集成 JPush 极光推送指北
我是一个 Laravel 小白,我是一个 Laravel 小白,我是一个 Laravel 小白(默念三遍再往下读,如果非小白就不用看了). Laravel 使用 Composer 来管理代码依赖.所以 ...
- Android来电、去电监听
Android手机中添加手机来电的状态,使用PhoneStateListener来监听. TelephonyManager telephonyManager = (TelephonyManager) ...
- unix高级编程阅读
一.进程: fork,exec,waitpid 1.子进程:复制进程的代码与堆栈状态,因此子进程将会从刚执行的指令fork位置继续往下执行. 2.父进程通过waitpid等待子进程完成 二.线程: 1 ...
- 怎么使用Vue-cli3开发像iview、element那样的组件可下载直接使用
https://www.cnblogs.com/wisewrong/archive/2018/12/28/10186611.html 参考这个就行. 而我这篇文章主要是对里面的相关步骤作一些简单的说明 ...
- 大数据平台-修改主机名及ssh免密码登录
一.查看服务器初始配置: 1.总核数 = 物理CPU个数 X 每颗物理CPU的核数 2.总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理CPU个数cat /pr ...