Question

I'm trying to convert this block of code to 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;
}

I've tried with that but I can't get it to work:

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 is structured this way:

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

Solution

I'm not convinced there's any direct problem with the conversion, but the original code appears flawed - if you have two consecutive functions that you are trying to delete, only the first one will be removed. Each time you delete something, you skip the following item in the list (you'd have to be a bit more clever with your indexes for it to work, unless you're indifferent to checking an item that follows the callback match for whatever reason). This can be fixed by doing something like this to the original code:

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

While it would work with different index manipulations, I would consider doing a more functional programming approach (that is what lodash and underscore are for, after all):

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

Rather than direct manipulation of existing data, functional programming emphasizes the immutability of existing data, and will typically rely the creation of a new structures to reflect a change to existing data. So, rather than splicing the existing arrays, the old structure is used to generate a new one, and the reference to the old one is replaced by a reference to the new one.

This doesn't quite explain the motivations behind the functional approach though, so I'll leave you with a few thoughts as to why this may be a better design decision. In this case, it may be better for performance (splicing an array multiple times is quite expensive). However, the more important part of functional programming is that you don't have to juggle state quite as much in variables, which can lead to more solid code. This is a perfect example of this - the indexing for manipulating the existing structure is harder to do correctly than having existing functions handle state for you (in this case, map and filter), which led to the indexing error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top