【问题标题】:Removing Element From Array of Arrays with Regex使用正则表达式从数组数组中删除元素
【发布时间】:2015-04-28 01:14:01
【问题描述】:

我正在使用正则表达式来测试数组数组中的某些元素。如果内部数组不遵循所需的格式,我想将其从主/外部数组中删除。我正在使用的正则表达式工作正常。我不确定为什么它没有被删除 - 任何人都可以建议或提供任何编辑来解决这个问题吗?

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);
}

【问题讨论】:

  • 你能用一些测试值创建一个 jsfiddle 吗?
  • 您是否尝试过正则表达式而不尝试匹配行首和行尾,即 ^ 和 $?

标签: javascript arrays regex node.js


【解决方案1】:

当您在数组上转换splice 方法时,它的length 会立即更新。因此,在未来的迭代中,您可能会跳过其中的一些成员。

例如:

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)

它会输出:

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"]

我的建议是,如果您仍然需要遍历数组,请不要修改数组本身。使用另一个变量来保存它。

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"]

或者你可以使用Array.prototype.filter,这更简单:

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

它还输出:

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

【讨论】:

  • @djfkdjfkd39939 不,i &lt; arr.length 每次迭代都会得到长度。如果你缓存了var i = 0, l = arr.length然后i &lt; l这样的长度,如果你访问一些还不存在的索引,你可能会遇到错误。
  • @djfkdjfkd39939 更新了我的示例,以便您可以看到在迭代中修改数组时会发生什么。
  • @djfkdjfkd39939 它应该可以工作。您遇到的根本原因与数组嵌套无关。
  • @djfkdjfkd39939 是的。您在遍历数组时正在操作数组。每次调用splice 时,它的长度和成员都会发生变化。阅读我回答中的第一个示例。
  • 在您的示例中,问题并不在于 length 本身不断变化,事情会被跳过,因为当您删除当前项目时,“下一个”项目与当前项目具有相同的索引一个做了。即使您删除了一个项目,for 语句也会在每一轮中不断增加 i,这就是导致跳过的原因。问题中的代码从末尾开始遍历数组并每轮递减,它不应该受到这种行为的影响,因为在删除较高索引时较低的索引不会改变。
【解决方案2】:

您的代码seems to work 给我。您帖子中的代码缺少 } 来关闭 for 语句,但这应该会导致脚本无法解析,甚至根本无法运行。

我同意 Leo 的观点,尽管使用 Array.prototype.filter 重写它可能会更简洁。

您问题中的代码作为过滤器看起来像这样:

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

jsFiddle

我假设它在您的实际代码中是 3 个不同的正则表达式,如果它们在您的代码中都相同,您可以通过定义 RegExp 文字一次来节省一点开销:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-02
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 2012-07-05
    • 2017-06-18
    • 1970-01-01
    相关资源
    最近更新 更多