在嵌套的每个中使用lodash / underscore

时间:2013-03-05 22:16:15

标签: javascript underscore.js lodash

我正在尝试将此代码块转换为Lo-Dash:

if(!event && callback){
  for(var ev in this._events){
    for (var i = 0; i < this._events[ev].length; i++) {
      if(this._events[ev][i].callback === callback){
        this._events[ev].splice(i, 1);
      }
    }
  }
  return;
}

我已尝试过,但我无法让它发挥作用:

if(!event && callback){
  _.each(this._events, function(ev){
    _.each(ev, function(trigger, i, ev){
      if(trigger.callback === callback) ev.splice(i, 1);
    });
  });
  return;
}

this._events以这种方式构建:

this._events = {
  ev1: [
    {callback: functions(){....}},
    {callback: functions(){....}}
  ],
  ev2....
}

1 个答案:

答案 0 :(得分:0)

我不相信转换有任何直接问题,但原始代码有缺陷 - 如果您有两个连续的功能要删除,则只删除第一个。每次删除某些内容时,都会跳过列表中的以下项目(您必须更加熟悉索引才能使其工作,除非您因为某种原因检查回调匹配后面的项目而无动于衷)。这可以通过对原始代码执行类似的操作来修复:

if (!event && callback) {
  for (var ev in this._events) {
    for (var i = 0; i < this._events[ev].length; i++) {
      if (this._events[ev][i].callback === callback) {
        this._events[ev].splice(i, 1);
        i--;
      }
    }
  }
  return;
}

虽然它可以用于不同的索引操作,但我会考虑做一个更具功能性的编程方法(毕竟lodash和下划线是用的):

if (!event && callback) {
  this._events = _.map(this._events, function(ev) {
    return _.filter(ev, function(trigger, i, ev) {
      return !(trigger.callback === callback);
    });
  });
  return;
}

功能编程不是直接操纵现有数据,而是强调现有数据的不变性,并且通常依赖于创建新结构来反映现有数据的变化。因此,不是拼接现有数组,而是使用旧结构生成新结构,并且对旧结构的引用将替换为对新结构的引用。

这并没有完全解释功能方法背后的动机,所以我会留下一些想法,为什么这可能是一个更好的设计决策。在这种情况下,性能可能更好(多次拼接阵列非常昂贵)。然而,函数式编程中更重要的部分是你不必在变量中处理相当多的状态,这可以导致更加可靠的代码。这是一个很好的例子 - 操作现有结构的索引比现有函数处理状态(在本例中为map和filter)更难以正确执行,这导致了索引错误。