groupByHash

Please note that Hash has been replaced by Map in Haxe 3.

This is a useful function from the HashTools haxelib:

I use this regularly with Xml data to quickly aggregate data into simpler/faster Hashes, GUI elements for more advanced interaction techniques, and a wide variety of different situations.

In general, it's useful any time I want to dynamically define "groups" in an Iterable, and I don't know beforehand which groups exist, let alone which elements belong to which group.

public static function groupByHash<A,B>(it : Iterable<A>, ?transformer : A -> String) : Hash<List<A>> {
    if (transformer == null) {transformer = function(x) {return Std.string(x);}}

    var r = new Hash<List<A>>(); 
    for ( i in it){ // go through the Iterable and add elements to Hash entries based on their transform
        var t = transformer(i);

        if (! r.exists(t)){    
            var l = new List<A>();

            l.add(i);
            r.set(t,l);
        }
        else { r.get(t).add(i); }
    }

    return r;
}

For instance, this call:

var someHash = groupByIntHash( [1.1 , 2.32, 3.51, 4.12, 1.15 ], Std.int);

will group the floats by their integer values:

HaXeProject.hx:15: {4 => {4.12}, 3 => {3.51}, 2 => {2.32}, 1 => {1.1, 1.15}}

It gets even simpler with "using":

using HashTools
...
var someHash = [1.1 , 2.32, 3.51, 4.12, 1.15].groupByIntHash(Std.int);

version #17855, modified 2013-03-03 05:41:31 by cambiata