Remove multiple elements from array in Javascript/jQuery

后端 未结 22 2103
梦毁少年i
梦毁少年i 2021-01-29 19:42

I have two arrays. The first array contains some values while the second array contains indices of the values which should be removed from the first array. For example:

<
相关标签:
22条回答
  • 2021-01-29 20:22

    It feels necessary to post an answer with O(n) time :). The problem with the splice solution is that due to the underlying implementation of array being literally an array, each splice call will take O(n) time. This is most pronounced when we setup an example to exploit this behavior:

    var n = 100
    var xs = []
    for(var i=0; i<n;i++)
      xs.push(i)
    var is = []
    for(var i=n/2-1; i>=0;i--)
      is.push(i)
    

    This removes elements starting from the middle to the start, hence each remove forces the js engine to copy n/2 elements, we have (n/2)^2 copy operations in total which is quadratic.

    The splice solution (assuming is is already sorted in decreasing order to get rid of overheads) goes like this:

    for(var i=0; i<is.length; i++)
      xs.splice(is[i], 1)
    

    However, it is not hard to implement a linear time solution, by re-constructing the array from scratch, using a mask to see if we copy elements or not (sort will push this to O(n)log(n)). The following is such an implementation (not that mask is boolean inverted for speed):

    var mask = new Array(xs.length)
    for(var i=is.length - 1; i>=0; i--)
      mask[is[i]] = true
    var offset = 0
    for(var i=0; i<xs.length; i++){
      if(mask[i] === undefined){
        xs[offset] = xs[i]
        offset++
      }
    }
    xs.length = offset
    

    I ran this on jsperf.com and for even n=100 the splice method is a full 90% slower. For larger n this difference will be much greater.

    0 讨论(0)
  • 2021-01-29 20:23

    Sounds like Apply could be what you are looking for.
    maybe something like this would work?

    Array.prototype.splice.apply(valuesArray, removeValFromIndexes );
    
    0 讨论(0)
  • 2021-01-29 20:23
    var valuesArr = new Array("v1","v2","v3","v4","v5");   
    var removeValFromIndex = new Array(0,2,4);
    
    console.log(valuesArr)
    let arr2 = [];
    
    for (let i = 0; i < valuesArr.length; i++){
      if (    //could also just imput this below instead of index value
        valuesArr[i] !== valuesArr[0] && // "v1" <--
        valuesArr[i] !== valuesArr[2] && // "v3" <--
        valuesArr[i] !== valuesArr[4]    // "v5" <--
      ){
        arr2.push(valuesArr[i]);
      }
    }
    
    console.log(arr2);
    

    This works. However, you would make a new array in the process. Not sure if thats would you want or not, but technically it would be an array containing only the values you wanted.

    0 讨论(0)
  • 2021-01-29 20:25

    There's always the plain old for loop:

    var valuesArr = ["v1","v2","v3","v4","v5"],
        removeValFromIndex = [0,2,4];    
    
    for (var i = removeValFromIndex.length -1; i >= 0; i--)
       valuesArr.splice(removeValFromIndex[i],1);
    

    Go through removeValFromIndex in reverse order and you can .splice() without messing up the indexes of the yet-to-be-removed items.

    Note in the above I've used the array-literal syntax with square brackets to declare the two arrays. This is the recommended syntax because new Array() use is potentially confusing given that it responds differently depending on how many parameters you pass in.

    EDIT: Just saw your comment on another answer about the array of indexes not necessarily being in any particular order. If that's the case just sort it into descending order before you start:

    removeValFromIndex.sort(function(a,b){ return b - a; });
    

    And follow that with whatever looping / $.each() / etc. method you like.

    0 讨论(0)
  • 2021-01-29 20:27

    Not in-place but can be done using grep and inArray functions of jQuery.

    var arr = $.grep(valuesArr, function(n, i) {
        return $.inArray(i, removeValFromIndex) ==-1;
    });
    
    alert(arr);//arr contains V2, V4
    

    check this fiddle.

    0 讨论(0)
  • 2021-01-29 20:27

    You could try and use delete array[index] This won't completely remove the element but rather sets the value to undefined.

    0 讨论(0)
提交回复
热议问题