グループ化したかった

Lo-Dashれない環境で。

var _groupBy = function(source, key) {
    var result = [],
        _index = function(array, f) {
            for(var i = 0, max = array.length; i < max; i++) {
                if(f(array[i])) return i;
            }
            return -1;
        };

    source.forEach(function(v) {
        var prop = typeof key === "function" ? key(v) : v[key],
            index = _index(result, function(o) { return prop in o; });
        if(index >= 0) {
            result[index][prop].push(v);
        } else {
            var obj = { key : prop };
            obj[prop] = obj["values"] = [v];
            result.push(obj);
        }
    });
    return result;
};

keyとvaluesは欲しかったので無理やり付けた感がある。
lodashだと返ってくるのがオブジェクトだったりチェインできたり遅延とかあるけどパフォーマンス特に気にしないで簡易的に使えればいいよねでこんな感じ。

var data = [
    { id : 1, name : "hoge" },
    { id : 2, name : "piyo" },
    { id : 3, name : "fuga" },
    { id : 1, name : "foo" },
    { id : 4, name : "hoge"}
];

_groupBy(data, "id")
    .forEach(function(group) {
        console.log(group);
        group.values.forEach(function(obj) {
            console.log(obj);
        });
});

f:id:ebifly10:20141106212826p:plain
プロパティ名でグループ化したり

_groupBy(data, function(obj) { return obj.name; })
    .forEach(function(group) {
        console.log(group);
        group.values.forEach(function(obj) {
            console.log(obj);
        });
});

f:id:ebifly10:20141106213024p:plain
関数渡してプロパティ指定したり

_groupBy(data, function(obj) { return obj.id % 2; })
    .forEach(function(group) {
        console.log(group);
        group.values.forEach(function(obj) {
            console.log(obj);
        });
});

f:id:ebifly10:20141106213303p:plain
boolean返す関数渡してtrue/falseでグループ化したりできていた。

lodashった結果だと配列っぽいオブジェクトで返ってくるしそっちのほうがよさげな雰囲気がありましたが、使おうと思っていた場所の処理を見なおしたらこんなの必要なかったとかなんとか。