js 根据指定的多个索引,删除相应的数组元素。splice + sort
更新于2018-04-19
var productItems = ["a", "b", "c", "d"]; var indexs = [1, 2, 3]; indexs.sort(function(a, b) { return b - a}); indexs.forEach(function(index) { productItems.splice(index, 1) })
将索引集合按照倒序排列,然后splice从数组尾巴开始删除,这样就不会数组的变化就不会影响删除的实现
这里可以直接使用 https://github.com/liyang0612/del-array-value
-----------------------------分割线---------------------------------
昨天遇到一个这样的场景: 有一个不分页的商品列表,里面可能有上千条数据(而且可能是静态数据)甚至更多,这里有个删除功能,需要我们删除其中的一些商品。
这时我的第一反应就是,数据过多不能循环整个数组,只有获取到它们的索引,然后循环得到的索引,使用数组的splice()方法对它进行删除。并且我这样做了,但是发现了一个致命的bug。
bug的原因是这样的: 我先得到了一组索引(就是我所需要删除的商品的索引),然后循环了这组索引,在每次循环的时候我执行了splie()方法,但是由于splice方法执行后会改变数组,所以我的数组长度减少了一;但是我所获取到的索引没有变,从而导致我的第二次splice的时候就出现了bug。
这些我想了另外一个方法:执行一次splice索引应该也减去 “1” 才对,所以我写了这样一个算法;假设所有的索引都为 “n”,并且它们是以正序排列的,那么splice一次之后数组减去 “1”,相应的“n”也减去 “1”;splice第二次之后,“n-2”;第三次之后,“n-3”;
发现这个规律之后我想到的就是,先把所所需要删除元素的索引计算出来。下面是一个例子:
var productItems = ["a", "b", "c", "d"]; var indexs = [1, 2, 3]; //先计算能被正常删除的索引: var newIndexs = indexs.map(function(val, idx){ return val - idx; }) /**因为splice是从第二次的时候出现bug的, *所以我们第一个索引的位置是正确的, *从第二次开始 “n-1”,也就是刚好对应索引数组的索引。**/ newIndexs.forEach(function(index){ productItems.splice(index, 1) }) productItems //最后得到 ["a"]
这一切都是建立在索引数组是正序排列的情况下,所以计算索引之前,先使用sort方法进行排序;
这样就实现了不循环整个数组,从而删除指定的某些元素。避免了由于数据过大造成的性能问题,毕竟每次删除都去循环几千条数据,这是很恐怖的!!!!