带有拼接的array.forEach是从唯一ID数组中删除条目的最佳方法吗?

时间:2014-10-26 09:06:40

标签: javascript

我有一个对象数组。每个对象都有一个唯一的userTestrId。这是我想要删除其中一个对象时使用的代码。这是我执行删除的最有效方法吗?我关心的是,一旦删除了一行,即使没有其他条目,代码仍然会一直在数组中运行:

var id = 99;
self.tests.forEach(function (elem, index) {
   if (elem['userTestId'] === id)
      self.tests.splice(index, 1);
   });
}

4 个答案:

答案 0 :(得分:3)

var id = 99;
self.tests.some(function (elem, index) {
   if (elem['userTestId'] === id)
      self.tests.splice(index, 1);
      return true;
   });
   return false;
}

可以使用Array.some吗?从回调中返回TRUE后停止循环。

答案 1 :(得分:2)

这是@ benhowdle89的答案的替代方案。

使用Array.prototype.every

.every方法用于迭代数组并检查每个元素是否通过测试。如果任何单个元素的回调返回false,则循环中断 请看以下示例:

var odds = [3, 5, 7, 9, 11, 12, 17, 19];
//an array with all odd numbers except one
var checkEven = function (n, i, arr) {
  console.log ("Checking number ", n);
  if (n%2===0) {
    arr.splice(i, 1);
    return false;
  }
  return true;
}
console.log(odds.every(checkEven), odds);

如果你运行上面的命令并查看控制台,循环只执行到12号,它拼接,然后停止。

您可以非常轻松地在代码中使用类似的逻辑:)

答案 2 :(得分:2)

var id = 99;
self.tests.some(function (elem, index) {
   if (elem['userTestId'] === id)
      self.tests.splice(index, 1);
      return true;
   });
   return false;
}

Polyfill: some已添加到第5版的ECMA-262标准中;因此,它可能不存在于标准的所有实现中。您可以通过在脚本的开头插入以下代码来解决此问题,允许在本机支持它的实现中使用一些代码。

// Production steps of ECMA-262, Edition 5, 15.4.4.17
// Reference: http://es5.github.io/#x15.4.4.17
if (!Array.prototype.some) {
  Array.prototype.some = function(fun /*, thisArg*/) {
    'use strict';

    if (this == null) {
      throw new TypeError('Array.prototype.some called on null or undefined');
    }

    if (typeof fun !== 'function') {
      throw new TypeError();
    }

    var t = Object(this);
    var len = t.length >>> 0;

    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++) {
      if (i in t && fun.call(thisArg, t[i], i, t)) {
        return true;
      }
    }

    return false;
  };
}

see详细信息

答案 3 :(得分:0)

虽然您的担忧在技术上是正确的,但它不太可能是一个实际问题(Javascript很快,这是一个微观优化)。

您应该做的是专注于使用适当的界面,以便您的代码易于阅读和理解。 .forEach()并没有告诉你你想要做什么,除非你真的想对数组的每个元素做些什么。

Lodash具有.remove()函数,该函数删除与谓词匹配的所有元素。不幸的是,我无法在JS的标准库或lodash中找到您想要的确切特定功能,因此您必须编写自己的包装器:

var id = 99
removeFirst(tests, function (elem) { return elem.userTestId === id })

function removeFirst(array, callback) {
    var index = array.findIndex(callback)
    array.splice(index, 1)
}

注意到,你应该避免使用一个数组 - 拼接比开始循环整个数组更昂贵!相反,由于您有唯一标识符,因此可以使用地图:

var map = {}
tests.forEach(function mapper(elem) {
    map[elem.userTestId] = elem
})

现在,您的删除功能只是delete map[id]