C#实现Javascript的Splice
程序员文章站
2022-10-11 09:10:02
最近开始学习javascript语言,看到splice方法,以下引用其说明:该方法是一个通用删除和插入元素的方法,它可以在数组指定的位置开始删除或插入元素。其包括3个参数:第一个参数指定插入的起始位...
最近开始学习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 = { 1, 2, 3, 4, 5, 6 }; int[] b = arrayhelper.splice(ref a, 2, 2); assert.equal(new int[] { 1, 2, 5, 6 }, a); assert.equal(new int[] { 3, 4 }, b); }
[fact] public void trancatearrayandinsertnewelements() { int[] a = { 1, 2, 3, 4, 5, 6 }; int[] b = arrayhelper.splice(ref a, 2, 2, 7, 8, 9); assert.equal(new int[] { 1, 2, 7, 8, 9, 5, 6 }, a); assert.equal(new int[] { 3, 4 }, b); }
代码的整体思路是,先新建两个数组,分别用于存放被删除元素和剩余的元素加上插入的新元素(如果有的话),然后把要删除的元素拷贝到用于保存被删除元素的数组,接着拷贝源数组删除位置前的需要保留的元素到新数组,然后把要插入的元素拷贝到新数组,最后把源数组末尾的元素拷贝到新数组。还是用代码说话会计较清楚:
public static t[] splice(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, 0, 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, 0, 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; }
通过写这段代码体会到了日常用惯了list等集合类,现在用数组去存放操作元素好像又回到c语言写代码的感觉,要注意数组下标、数组边界和数组的大小。
上一篇: 网站架构发展历程