Nested Public Modules

    groupbyfunctions

    0.1.6 • Public • Published

    groupbyfunctions

    global, easy to use, group by functions on objects. like linq - but much more simple and functional javascript

    Here are few function I used to copy paste to do simple jobs.

    So I decided to make them global and make a module from them.

     
    tests:
     
      groupby
        ✓ should sort items into buckets. return an object - put each item of an array into an object property, according to value of a specified field
     
      objeach
        ✓ should be iterate for each on object's properties
     
      objmap
        ✓ should be return a new object with same names and values updated by map function
     
      objfilter
        ✓ should be return a new object with properties filtered by their value
     
      sortobj
        ✓ should sort object's keys by their names
        ✓ should be able to use optional comparator
     
      sortobjkey
        ✓ should sort object's keys by value is desc order
     
      sortkeys
        ✓ should sort object's keys by their names
        ✓ should be able to use optional comparator
     
      objtokvarr
        ✓ should convert object to array of objects of key and value
        ✓ should be able to use defined names
     
      objtsv
        ✓ should convert array of objects to tab seperated values string
     
     
      12 passing (33ms)

    npm install groupbyfunctions

    examples use:

     
    var items=[
    {id:1,kind:'type-b',value:997454},
    {id:2,kind:'type-a',value:12132},
    {id:3,kind:'type-a',value:451},
    {id:4,kind:'type-c',value:7894}];
     
     
    require('groupbyfunctions')
     
     
     
     
     
    groupby(items,'kind') 
    //result:
    { 'type-b': [ { id: 1, kind: 'type-b', value: 997454 } ],
      'type-a':
       [ { id: 2, kind: 'type-a', value: 12132 },
         { id: 3, kind: 'type-a', value: 451 } ],
      'type-c': [ { id: 4, kind: 'type-c', value: 7894 } ] }
     
     
     
    sortobj(groupby(items,'kind'),function(av,bv,ak,bk){return bv.length-av.length})
    //result:
    { 'type-a':
       [ { id: 2, kind: 'type-a', value: 12132 },
         { id: 3, kind: 'type-a', value: 451 } ],
      'type-b': [ { id: 1, kind: 'type-b', value: 997454 } ],
      'type-c': [ { id: 4, kind: 'type-c', value: 7894 } ] }
     
    objmap(   groupby(items,'kind')  ,  function(items){ return items.length}  )
    //result:
    { 'type-b': 1, 'type-a': 2, 'type-c': 1 }
     
     
    objfilter(groupby(items,'kind'),function(v,k,i){ return v.length>1})
    //result:
    { 'type-a':
       [ { id: 2, kind: 'type-a', value: 12132 },
         { id: 3, kind: 'type-a', value: 451 } ] }
     
     
     
         
    var menu=objtokvarr(groupby(items,'kind'),'name','children')
    // result:
    [ { name: 'type-b',
        children: [ { id: 1, kind: 'type-b', value: 997454 } ] },
      { name: 'type-a',
        children:
         [ { id: 2, kind: 'type-a', value: 12132 },
           { id: 3, kind: 'type-a', value: 451 } ] },
      { name: 'type-c',
        children: [ { id: 4, kind: 'type-c', value: 7894 } ] } ]
     
     
     
     
    //write single level object to string file (tab-seperated-values)
    fs.writeFileSync('items.tsv',objtsv(items));
     
     

    the functions:

     
     
    // receives an array
    // returns an object,
    //  the keys of it are as value of specified field,
    //  the values of it are arrays of elements.
    groupby=function (objarr,field)
    {
        var existingGroups=[];
        var grouped={};
        objarr.forEach(function(obj)
        {
            var groupname=obj[field];
            if(groupname in grouped)
             grouped[groupname].push(obj);
            else
             grouped[groupname]=[obj];
        });
        return grouped;
    }
     
    // for each on object keys
    //objeach(obj, function(value,key,index){ } )
    objeach=function (obj,func)
    {
        return Object.keys(obj).forEach(function(k,i)
        {
            return func(obj[k],k,i);
        });
    }
     
    //var obj=objmap(obj, function(value,key,index){ return value.field ; } )
    objmap=function (obj,func)
    {
     var r={};
     objeach(obj,function(v,k,i){r[k]=func(v,k,i)})
     return r;
    }
     
     
    //var obj=objmap(obj, function(value,key,index){ return value.field ; } )
    objfilter=function (obj,func)
    {
     var r={};
     objeach(obj,function(v,k,i){ if(func(v,k,i)) r[k]=v})
     return r;
    }
     
    // sort object keys by theis values
    // sortobj(obj);
    //
    // sortobj(obj,function compfunc(a,b,aname,bname){ return b.field - a.field; });
    //
    //  comparator function is optional:
    //   a comparator function returns 0 if parameters eqals,
    //   a larger than zero value if a larger than b, or 
    //   a less than zero value if a is smaler than b
    //
    //  in my comparator there are also aname and bname arguments it is possible to use them optionally.
    //
    //  exampels for comparator functions
    //
    //  //objct's sub property
    //  sortobj(obj,function compfunc(a,b,aname,bname) 
    //  {
    //    if(a.field>b.field) return 1;
    //    if(a.field<b.field) return -1;
    //    return 0
    //  })
    //
    //  //multiple columns sort
    //  sortobj(obj,function compfunc(a,b,aname,bname) 
    //  {
    //    if(a.field>b.field) return 1;   // first sort by this fileld
    //    if(a.field<b.field) return -1;
    //
    //    if(a.fieldb>b.fieldb) return 1; // if fields above is eqals, then sort by this fileld
    //    if(a.fieldb<b.fieldb) return -1;
    //
    //    return 0 // if everything eqals return equals
    //  })
    //
    //  sort by integer, maybe desc (swap fields if needed)
    //  sortobj(obj,function compfunc(a,b,aname,bname){return b.field - a.field;}
    //
    //  sort by string using unicode char order
    //  sortobj(obj,function compfunc(a,b,aname,bname)
    //  {
    //    return a.localeCompare(b)
    //  })
    //
    //  sort object  by keys
    //  sortobj(obj,function compfunc(a,b,aname,bname)
    //  {
    //            if(aname>bname) return 1;if(aname<bname) return -1;
    //            return 0
    //  })
    //
    //
     
    //
    sortobj=function (obj,compfunc)
    {
        var comp;
        if(!compfunc)
          comp=function(a,b){
                if(a[1]>b[1]) return 1;if(a[1]<b[1]) return -1;
                return 0
              };
        else 
          comp=function(a,b){
                return compfunc(a[1],b[1],a[0],b[0])
              };
        
        var keys=Object.keys(obj);
        var kva= keys.map(function(k,i)
        {
            return [k,obj[k]];
        });
        kva.sort(comp);
        var o={}
        kva.forEach(function(a){ o[a[0]]=a[1]})
        return o;
    }
     
     
     
    // quickly sort an object's keys by value is desc order, like: to get top rows
    sortobjkey=function (obj,key)
    {
        var o={}
        Object.keys(obj).map(function(k,i) {
            return [k,obj[k]];
        }).
         sort(function(a,b){
          k=key;      if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
          return 0
         }).
          forEach(function(a){ o[a[0]]=a[1]})
        return o;
    }
     
    // quickly sort an object's keys by their name
    sortkeys=function (obj,comp)
    {
        var o={}
        Object.keys(obj).
         sort(comp).
          forEach(function(k){ o[k]=obj[k]});
        return o;
    }
     
    // convert object to array of objects of key and value
    // obj={aa:123}
    // var arr=objtokvarr(obj) // arr=[ {k:aa,v:123} ]
    // var arr=objtokvarr(obj,"name","value") // arr=[ {name:aa,value:123} ]
    objtokvarr=function (obj,k,v)
    {
        if(!k) k="k";
        if(!v) v="v";
        var keys=Object.keys(obj);
        var r=[];
        keys.forEach(function(kk,i)
        {
            var o={};
            o[k]=kk;
            o[v]=obj[kk];
            r.push(o);
        });
        return r;
    }
     
    // converts array of objects to a text table
    // columns seperated by tabs
    // first row is key names.
    //
    // (its something you can paste in to excel, or save to tsv file)
    // 
    // var products=[{id:1,name:"aaa"},{id:2,name:"bbb"}]
    // fs.writeFileSync('products.tsv',objtsv(products));
    // result is like:
    // id name
    // 1  aaa
    // 2  bbb
    //
    objtsv=function (arr_of_obj)
    {
        if(arr_of_obj.length==0) return " no data ";
        if(! (arr_of_obj instanceof Array) ) return " not an array ";
        
        var keys=Object.keys(arr_of_obj[0]); //assume all keys same as first
        
        var table=arr_of_obj.map(function(obj)
        {
         return  keys.map(function(k) { return obj[k]; }).join('\t')
        })
     
        return [keys.join('\t')].concat(table).join('\r\n');
    }
     
     

    tests

    for tests need to instal mocha:

    npm install -g mocha
    

    then to run a test

    mocha test.js
    

    Licence

    Generaly, 2 close MIT/BSD - Copyright: Shimon Doodkin helpmepro1@gmail.com (http://doodkin.com)

    But you can use it as you like, I don't care , Enjoy.

    Install

    npm i groupbyfunctions

    DownloadsWeekly Downloads

    5

    Version

    0.1.6

    License

    MIT

    Last publish

    Collaborators

    • shimondoodkin