Wednesday, June 27, 2007

the way forward

I think I have found the way forward! And it's Array.prototype.groupBy.

So the "show a list of things grouped according to some criteria" functionality is one of the main sources of slowness in MGTD alpha. While adding the "go faster" code (work in progress in the svn trunk but not released yet) I attempted a rewrite of the grouped list functionality to be more efficient, but the new version was quite ugly and inelegant and I was finding bugs that I was having trouble squashing. Anyway I was reading an article about some new features in ruby 1.9 and it mentioned groupBy method for arrays. It didn't really describe it much but just the mention of it was enough and later that night I scribbled this on a piece of paper.

merge(Array.prototype,{

  groupBy: function(callback) {
    var result = {};
    var leftOverGroup = '__NONE__';
    this.each(function(item) {
      var groups = callback(item);
      if (groups.length > 0) {
        groups.each(function(group) {
          if (!result[group])
            result[group] = [];
          result[group].push(item);
        });
      }
      else {
        if (!result[leftOverGroup])
          result[leftOverGroup] = [];
        result[leftOverGroup].push(item);
      }
    });
    return result;
  }

});
or at least something pretty close to it. It pretty much does the same thing as my existing code but it's much cleaner and much more ruby-esque. It also removes the presentation layer from the logic which has to be a good thing. The function you pass in should return an array of "groups" that the item belongs to. Example usage:
var test = ["Apples","Anchovies","Cupcakes","Zorro"].groupBy(function(x){
  return x == "Zorro" ? [] : [x.substr(0,1)];
});

/*
test is now this:
{
  A: ["Apples","Anchovies"],
  C: ["Cupcakes"],
  __NONE__: ["Zorro"]
}
*/

// possible usage in MGTD
var list = config.indexedTags.tagLists.Project.groupBy(function(t){
  config.indexedTags.indexes[t].Area;
});
Note that __NONE__ is where the leftovers go so for example projects with no area, or actions with no context. There's still some work to do on rendering and sorting the result, and actually it still won't give me projects with no next actions, but I'm confident that's it's a step in the right direction.

5 Comments:

Blogger Jeremy said...

Yum, that's very nice. Rock on the unification of Ruby and JavaScript :)

3:14 PM PDT  
Blogger Andrew Codrington said...

People who scribble that neatly on paper, in white on black no less, are not to be trusted. :-)

Sounds promising!

7:35 AM PDT  
Blogger Felix Wonderland said...

I'm really glad to hear that there are new enhancements coming out for MGTD!

I actually found this post by googling "improve tiddlywiki speed" and behold! You're already on top of the issue.

Can't wait for the new version (but I will have to)
-Felix

10:31 PM PDT  
Anonymous Anonymous said...

Ran across monkey less than a week ago, and I'm in love. My productivity went up after running MGTD with WebRunner - no more lure of the interwebs, just clean tasks and projects.

9:25 AM PDT  
Anonymous Anonymous said...

I'd like to ask you how could I do total translation of mgtd? I've translated all thungs from native TW (it is very easy) But it seems that I have to translate a lot of tiddlers in the end of the file to get mgtd translation? Is there any other way?

1:27 PM PDT  

Post a Comment

<< Home