0

I've read several questions about this on StackOverflow, and found some solutions even, but they all seem to do the same weird thing:

I have an array (array A) of 8 names:

arrayA= ["person1", "person2", "person3", "person4", "person5", "person6", "person7", "person8"];

And I have an array (array B) of 1 name:

arrayB= ["person1"];

Now, I want to remove all names that do not occur in Array B, from Array A.

So I wrote a little function which loops through all items in Array A, and checks if they occur in Array B. If they do not, I remove them from Array A.

So I looked for a function to remove strings from an array (in PHP, this is all so much easier...), and I found several methods, which all give me exactly the same problem. In the example below, I chose the cleanest method, using jquery's $.grep:

arrayA= ["person1", "person2", "person3", "person4", "person5", "person6", "person7", "person8"];
arrayB= ["person1"];

for (var i = 0, len = arrayA.length; i < len; i++) {
			
  if($.inArray(arrayA[i], arrayB) == -1){

    var removeName= arrayA[i];

    console.log('Removing row of: ' + removeName);

    /*
    $('tr[player=\'' + removeName + '\']').find('td')
    .wrapInner('<div style="display: block;" />')
    .parent()
    .find('td > div')
    .slideUp(700, function(){
      $(this).parent().parent().remove();
    });
    */

    arrayA= $.grep(arrayA, function(value) {
      return value != removeName;
    });
    
    console.log('arrayA now consists of: ' + arrayA);

  }

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

As you can see, it only removes the "even" items from arrayA, i.e. "person2", "person4", "person6" and "person8".

If I execute this function multiple times, the 2nd time it removes again only the "even" items (which is now "person3" and "person7"), and the third time, it removes "person5" (finally)...

Can someone please tell me what I'm not seeing? You can see from the console log that, the first time you run it, all the "odd" items in the array, (i.e. person3, person5 and person7) are "undefined"...

10
  • What is purpose of using for loop? Is requirement to remove elements from original array or return new array having only elements that are within arrayB? Commented Feb 11, 2017 at 23:40
  • 1
    You're reindexing (or actually replacing) the array while iterating it. In other words, when you remove one, the next index becomes current, and so it gets skipped over when the loop goes to the next item. Commented Feb 11, 2017 at 23:40
  • Yeah, I guessed it must have been something like that. Could you maybe provide me with a solution to remove all items from array A that do not occur in array B at once, without having to loop through it and remove them one by one? Commented Feb 11, 2017 at 23:45
  • so arrayA should become as ["person1"] after filtering? What is the benefit? eventually arrayA and arrayB will become equal. What's the point? Commented Feb 11, 2017 at 23:48
  • I think what you're after is to filter arrayB of ones that are in arrayA, and save that to arrayA... arrayA = arrayB.filter(function(s) { return arrayA.includes(s) }) Commented Feb 11, 2017 at 23:52

2 Answers 2

2

You can use do..while loop, Array.prototype.splice() to remove elements from an array

arrayA= ["vincent"
        , "Rumpelstilzchen"
        , "LuckeR"
        , "Nordland"
        , "Siegfried"
        , "NeKrone"
        , "Carnage"
        , "tom59fr"];
arrayB= ["vincent"];

var i = 0;

do {
  if (arrayB[0] !== arrayA[i]) {
    arrayA.splice(i, 1);  
  } else {
  ++i;
  }
} while (i < arrayA.length);
delete i;

console.log(arrayA, arrayB);

Sign up to request clarification or add additional context in comments.

1 Comment

Cool! That actually works! Thanks to the comment of @squint, I managed to get it working by running my for-loop backwards, to prevent shifting of the array-index which would cause it to skip every 'even' item: for (var i = arrayA.length-1; i >= 0; i--) { But this is way more elegant. Thanks!
1

This is because when you call this:

arrayA= $.grep(arrayA, function(value) {
  return value != removeName;
});

The length of arrayA changes, thus arrayA[k] will move to the position of arrayA[k-1] (when k>i).

So we'd better create a new array to store the filtered items and after the iteration, give its value to arrayA.

arrayA= ["person1", "person2", "person3", "person4", "person5", "person6", "person7", "person8"];
arrayB= ["person1","person4"];
var arrayC=[];
for (var i = 0, len = arrayA.length; i < len; i++) {
  console.log('inArray:'+$.inArray(arrayA[i], arrayB))
  if($.inArray(arrayA[i], arrayB) != -1){
    arrayC.push(arrayA[i]);
  }
  console.log('arrayC now consists of: ' + arrayC);
}
arrayA=arrayC;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

1 Comment

Thanks! I managed to prevent the shifting of indexes, by going through the array backwards (starting with var i = arrayA.length-1, and going down with i--, but your solution is cool too!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.