npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jsgjs

v0.4.0

Published

js module for simple SQL like operations on tablular-like data (Arrays of JSON objects)

Downloads

7

Readme

jsgjs

Join Select Group-js. A small utility for performing SQL like join select and group operations on Arrays of Objects in JS

JSG js

Join Select Group-js. A small utility for performing SQL like join select and group operations on Arrays of Objects in JS. With high perfomance on large data sets.

Useful for front-end data manipulation and backend datastreaming and analysis without Db storage. ie. combining analytic data from an third party api wiith in house Db.

Installation

npm install jsgjs --save

Node

var JSG = require("jsgjs");

Browser

Also included is a frontend jsgjs.min.js file

<script type="text/javascript" src="/servingDirectory/jsgjs.min.js"></script>
var useableObject = new JSG(initData);

Usage

A creted JSG object has 3 possible methods for manipulating data: -Join -Select -Group

Here is an example of all three used on two data sets

var JSG = require('jsgjs');
var users = [
	{id:1,name:"John"},
	{id:2,name:"Kate"},
	{id:3,name:"Mary"},
	{id:4,name:"Michal"},
];
var orders = [
	{user_id:2,items:1,price_cents:100},
	{user_id:2,items:5,price_cents:10000},
	{user_id:3,items:2,price_cents:500},
	{user_id:1,items:1,price_cents:1100},
];

var spendData = new JSG(users).select([
	{title:"user_id",val:"id"},
	"name"
]).leftJoin(orders,"user_id").group(
	"name",
	["price_cents::sum","items::avg"]
).select([
	"name",
	"items_avg",
	{title:"euros_spent",val:function(row){
		return row.price_cents_sum/100
	}}
]).result(); 
console.log(spendData)

// Result
[ { name: 'John', items_avg: 1, euros_spent: 11 },
 { name: 'Kate', items_avg: 3, euros_spent: 101 },
 { name: 'Mary', items_avg: 2, euros_spent: 5 },
 { name: 'Michal', items_avg: NaN, euros_spent: 0 } ] }

JSG Object

The JSG object provides routes by which to preform the join, group and select methods. It stores and then removes transient data from memory. It takes one argmument which is an array of JSON objects. This argument acts as the left dataset for a join and the primary dataset other operations.

var names = [
	{id:1,name:"Kate"},
	{id:2,name:"Mary"},
];
var dataObject =  new JSG(names);
console.log( dataObject.data , dataObject.result() ) // both return the names data set

When join , select or group methods are executed the results overwrite the previous 'data' property of the JSG object (ie. dataObject.data from above)

Join

The Join method creates a join object on which four joins can be preformed:

  • outterJoin
  • innerJoin
  • leftJoin
  • rightJoin

These mirror SQL like join in behaviour. rightJoin is simply a left join but inverts the dataSource.

var colours =[
	{name:"kate",colour:"blue"},
	{name:"john",colour:"red"},
	{name:"james",colour:"grey"},
];
var foods =[
	{name:"kate",colour:"chips"},
	{name:"john",colour:"apples"},
];
var leftJoinEx = new JSG(colours).leftJoin(foods,"name").result()
var rightJoinEx = new JSG(foods).rightJoin(colours,"name").result()

//leftJoinEx and rightJoinEx both return
//[ { name: 'kate', 'colour-left': 'blue', 'colour-right': 'chips' },
//{ name: 'john', 'colour-left': 'red', 'colour-right': 'apples' },
//{ name: 'james', 'colour-left': 'grey', 'colour-right': null } ]
// Join syntax is as follows 
var myJoinObject  = new JSG(dataSource1)[typeofJoin](dataSource2,"fieldToJoinOn")

The Join field must exist in both dataSets. If names are different as in the first example (ie join user_id and id) then a select statement or indeed a native array.map() function should be used.

N.B Currently the first row of each data set is used for header evaluation so ensure all relatvent headers are therein contained. There is an assumption of data validity

Select

Select provides similar functionality to the native .map method. However It provides utility in syntax and also in the context of other JSG methods

It takes one argument - selectionArray

Each element in the selectionArray maps one column

A selectionArray element can come in three forms

  1. String
  2. Object of form: {title:string, val:string }
  3. Object of form: { title:string, val:function }
var orders = [
  	{user_id:2,items:1,price_cents:100},
  	{user_id:2,items:5,price_cents:10000},
  	{user_id:3,items:2,price_cents:500},
  	{user_id:1,items:1,price_cents:1100},
];
var selectionArray = [
	{title:"user",val:"user_id"}, //maps the field user_id onto a new field named user
	"price_cents", // this maps the field transparently
	{title:"price_euros",val:function(row){return row.price_cents/100}} // this operates on each row
]
// note that items is ommited and therefore will be omitted from the results set

var result = new JSG(orders).select(selectionArray).result()
// result
// [ { user: 2, price_cents: 100, price_euros: 1 },
// { user: 2, price_cents: 10000, price_euros: 100 },
// { user: 3, price_cents: 500, price_euros: 5 },
// { user: 1, price_cents: 1100, price_euros: 11 } ]

Group

Group allows aggregation of data rows. Group takes two arguments:

  1. GroupBy
  • The field (string) or fields (array of strings) by which to group
  • "All" is another valid input (which does what it says on the tin)
  1. Field(s) to Aggregrate
  • This field provides some syntax freedoms.

Fields Argument

The Basic form is as per below

{header:"columnName::string",operators:["agerateFunctionName::string"]}

eg: [{header:"price_cents",operators:["sum","avg","count"]}]

A plain array of strings with columnName and operation seperated by the deliminator :: may also be used

	eg: ["price_cents::sum","price_cents::avg"]

NB : this second option is parsed into the first

Available Operators:

  • sum - numeric values only , disregarding null values
  • avg - numeric values only , disregarding null values
  • count - all values , disregarding null values
  • unique - all values , disregarding null values
  • median - numeric values only , disregarding null values
  • mode - all values , disregarding null values
  • max - numeric values only , disregarding null values
  • min - numeric values only , disregarding null values
var orders = [
    {user_id:2,items:1,price_cents:100},
    {user_id:2,items:5,price_cents:10000},
    {user_id:3,items:2,price_cents:500},
    {user_id:1,items:1,price_cents:1100},
];
var syntax1 = new JSG(orders).group("All",[
    {header:"price_cents",operations:["sum","avg","median","max"]},
    {header:"items",operations:["count","min","sum"]}
]).result();

var syntax2 = new JSG(orders).group("All",[
	"price_cents", // "price_cents" is parsed as "price_cents::sum" by default
	"price_cents::avg",
	"price_cents::median",
	"price_cents::max",
	"items",
	"items::count",
	"items::min"
]).result();

syntax1 and syntax2 will bring the same results

	// the output of results
result = [ { 
	All: undefined,
    price_cents_sum: 11700,
    price_cents_avg: 2925,
    price_cents_median: 1100,
    price_cents_max: 10000,
    items_count: 4,
    items_min: 1,
    items_sum: 9 
 }];

Filter (where/having)

Remove rows that dont meet a certain test. Syntax where , filter or having may be used. The one argument is a function that returns a boolean.

var rows = [
	{name:"kate",age:30},
	{name:"john",age:20},
	{name:"kate",age:1},
	{name:"mary"},
];
var filtered = new JSG(rows).filter(function(row){
	return row.age > 10
}).result()

[
	{name:"kate",age:30},
	{name:"john",age:20},
];

Sort (orderBy)

Sort the data according to one field/ column name by ascending (asc) or decending (desc) sort or orderBy methods can be used. The take one or two argument.

  • .sort("column","direction")
  • .sort("column::direction")
var rows = [
	{name:"kate",age:30},
	{name:"john",age:20},
	{name:"kate",age:1},
	{name:"mary",age:16},
];
var sorted = new JSG(rows).sort("age::asc").result()
var sorted = new JSG(rows).sort("age","asc").result()
var sorted = new JSG(rows).sort("age",1).result()

[ { name: 'kate', age: 1 },
  { name: 'mary', age: 16 },
  { name: 'john', age: 20 },
  { name: 'kate', age: 30 } ]

Release History

  • 0.1.0 Initial release