按参数删除数组元素 (Drop it)
题目链接
问题解释
- 这个
function接受一个数组参数arr和一个函数参数func。返回值为arr第一个满足参数func的元素及其之后的所有元素 - 如果
arr是[1, 2, 3, 4],func是function(n) {return n >=3;},那么此时返回值应为[3, 4] - 更值得关注的是这样的情况,如果
arr是[0, 1, 0, 1],func是function(n) {return n === 1;},那么此时返回值应为[1, 0, 1]
基本解法
思路提示
- 这道题目和上一道 Finders Keepers 的基本思路很相似,难度也很低。区别仅仅在于 Finders Keepers 需要返回一个元素,这道题是返回一个数组
- 题目说明中提到,这道题可以用到
Array.shift()。尽管我觉得不是很必要,但我们还是先来看看如何用这个方法以及循环写
参考链接
代码
1 | function drop(arr, func) { |
解释
- 首先,这里需要存一份原数组的深拷贝。深拷贝的意思是,就算原数组修改,这份拷贝也不会被影响。你可以执行一下这段代码,来比较一下深拷贝 (Hard Copy, Deep Copy) 与浅拷贝 (Shallow Copy) 的区别
1 | var arr = [1, 2, 3, 4]; |
- 不难看出,其中
shallowCopy会变化,而hardCopy不会变 - 至于为什么需要存一份深拷贝,原因很简单。我们在移除数组元素的时候,会使整个数组的长度变短。相当于,如果第一个元素被移除了,而我们又执行了
i++,那就会跳过原数组中第二个元素的判断,直接去判断原数组中的第三个了 - 如果我们存了一份拷贝,那么我们循环的参考依然是原来的那个
arr,而执行删除元素的是那份深拷贝,因此互相之间是不会有任何影响的 - 顺便,深拷贝的方式有很多,我们也可以新建一个空数组,然后遍历
arr,然后把其中的每个元素push到新建数组中。以下再列举六种深拷贝数组的方式:
1 | var arr = [1, 2, 3, 4]; |
- 多说一句,其实有些方法是有适用条件的。我个人比较喜欢用
arr.slice(),但这种只适用于arr中都是Primitive Type(原始类型) 元素的情况 - 当然,除了存一份拷贝,我们还有其他方式去解决,比如,删除元素的时候执行以下
i--可以是一种做法;再比如,从右边遍历也可以是一种做法。有兴趣的朋友可以自己写一下试试 - 最后需要单独返回一下
[]。因为如果所有元素都不满足func,则应该返回[]
推荐写法
思路提示
- 题目还给出了使用
Array.slice方法的提示。我们来看一看如何用这个方法解题 - 对于这道题目,关键就在于如何找到第一个使得测试函数
func返回值为true的元素。只要找到了,我们只需要用一下slice,一直截取到数组终点就可以了
参考链接
代码
1 | function drop(arr, func) { |
解释
- 跟前一种思路类似。但这里,我们不再需要存储数组的拷贝,也不需要再执行删除元素操作
- 这里的思路是,我们去找到第一个使得
func返回true的元素的index(索引),然后直接slice一下就可以了。slice方法如果只传入一个参数,那么就会一直截取到结尾