更新于2018-04-19



var productItems = ["a", "b", "c", "d"];

var indexs = [1, 2, 3,];

productItems.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[index].splice(index, 1)

})

productItems  //最后得到  ["a"]



  

这一切都是建立在索引数组是正序排列的情况下,所以计算索引之前,先使用sort方法进行排序;

这样就实现了不循环整个数组,从而删除指定的某些元素。避免了由于数据过大造成的性能问题,毕竟每次删除都去循环几千条数据,这是很恐怖的!!!!