简体   繁体   中英

Removing Element From Array of Arrays with Regex

I'm using regex to test certain elements in an array of arrays. If an inner array doesn't follow the desired format, I'd like to remove it from the main/outer array. The regex I'm using is working correctly. I am not sure why it isn't removing - can anyone advise or offer any edits to resolve this problem?

for (var i = arr.length-1; i>0; i--) {

      var a = /^\w+$/;
      var b = /^\w+$/;
      var c = /^\w+$/;  

    var first = a.test(arr[i][0]);
    var second = b.test(arr[i][1]);
    var third = c.test(arr[i][2]);

if ((!first) || (!second) || (!third)){
arr.splice(i,1);
}

When you cast splice method on an array, its length is updated immediately. Thus, in future iterations, you will probably jump over some of its members.

For example:

var arr = ['a','b','c','d','e','f','g']

for(var i = 0; i < arr.length; i++) {
  console.log(i, arr)
  if(i%2 === 0) {
    arr.splice(i, 1) // remove elements with even index
  }
}

console.log(arr)

It will output:

0 ["a", "b", "c", "d", "e", "f", "g"]
1 ["b", "c", "d", "e", "f", "g"]
2 ["b", "c", "d", "e", "f", "g"]
3 ["b", "c", "e", "f", "g"]
4 ["b", "c", "e", "f", "g"]

["b", "c", "e", "f"]

My suggestion is, do not modify the array itself if you still have to iterate through it. Use another variable to save it.

var arr = ['a','b','c','d','e','f','g']
var another = []

for(var i = 0; i < arr.length; i++) {
  if(i%2) {
    another.push(arr[i]) // store elements with odd index
  }
}

console.log(another) // ["b", "d", "f"]

Or you could go with Array.prototype.filter , which is much simpler:

arr.filter(function(el, i) {
  return i%2 // store elements with odd index
})

It also outputs:

["b", "d", "f"]

Your code seems to work to me. The code in your post was missing a } to close the for statement but that should have caused the script to fail to parse and not even run at all.

I do agree with Leo that it would probably be cleaner to rewrite it using Array.prototype.filter though.

The code in your question would look something like this as a filter:

arr = arr.filter(function (row) {
  return /^\w+$/.test(row[0]) && /^\w+$/.test(row[1]) && /^\w+$/.test(row[2]);
});

jsFiddle

I'm assuming it is 3 different regular expressions in your actual code, if they are all identical in your code you can save a little overhead by defining the RegExp literal once:

arr = arr.filter(function (row) {
  var rxIsWord = /^\w+$/;
  return rxIsWord.test(row[0]) && rxIsWord.test(row[1]) && rxIsWord.test(row[2]);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM