Skip to content

Instantly share code, notes, and snippets.

@konijn
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save konijn/2d2737b0f86792e27b32 to your computer and use it in GitHub Desktop.
Save konijn/2d2737b0f86792e27b32 to your computer and use it in GitHub Desktop.
var Hmm = (function()
{ //A snippet/library to find records in table-like JS arrays
function getNamedValue( o , name )
{ //Name can have dots, 'car.tire.brand.name' should get the expected
var parts = name.split(".");
while( parts.length && o ){
o = o[parts.shift()];
}
return o;
}
function unique( )
{ //Assuming `this` is an array, will copy all unique entries of `this` to a returned new array
var array = [], map = {}, json;
this.forEach( function( value ){
if( value instanceof Object ){
json = JSON.stringify( value );
if( !map[json] ){
array.push( value );
map[json] = true;
}
}
else if( !~array.indexOf( value ) ){
array.push( value );
}
});
return array;
}
function Hmm( data )
{ //data could be a string -> treat as JSON, parse it
//data could be an object, or a string that got converted to an object -> convert to array
//data could be an array ( original or through conversion ) -> leave as is
if( !(this instanceof Hmm) )
return new Hmm( data )
this.data = data instanceof Object ? data : JSON.parse( data );
this.data = this.data.length && this.data[0] ? Array.prototype.slice.call( this.data ) : this.data;
this.data = this.data instanceof Array ? this.data : [ this.data ];
}
Hmm.prototype.index = function( name )
{ //Name can have dots, 'car.tire.brand.name' should get the expected
//Generates an index object
var index = {} , i;
this.data.forEach( function( value )
{
var key = getNamedValue( value , name ),
keys = key instanceof Array ? key : [key];
for( i = 0 ; i < keys.length ; i++ )
{
key = keys[i];
index[key] = index[key] || [];
index[key].push( value );
}
});
return index;
};
Hmm.prototype.uniqueIndex = function( name )
{ //Create an index, point each index to the first of possible values
var index = this.index( name );
Object.keys( index ).forEach( function(key){
index[key] = index[key][0];
});
return index;
};
Hmm.prototype.collect = function( name )
{ //Collect all the values for a given property name
var values = this.data.map( function ( o ) {
return getNamedValue( o , name );
});
values.unique = unique;
return values;
};
Hmm.prototype.toString = function()
{ //More for jsbin than anything else
return JSON.stringify( this.data );
};
return Hmm;
}());
//Some tests
var foods = [
{ name : 'potatoes' , calories : 100 , allergens : [] , storage : 'ambient' },
{ name : 'pistachio ice cream' , calories : 1000 , allergens : ['nuts','milk'] , storage : 'frozen' },
{ name : 'chocolate ice cream' , calories : 1200 , allergens : ['milk'] , storage : 'frozen' },
{ name : '2% fat milk' , calories : 600 , allergens : ['milk'] , storage : 'chilled' }
];
var hmm = new Hmm( foods );
console.log( hmm.collect('name') ); //Collect all names
console.log( hmm.collect('allergens') ); //
console.log( hmm.collect('allergens').unique() );
console.log( hmm.collect('allergens.0') );
console.log( hmm.collect('allergens.0').unique().sort() );
console.log( hmm.index('name') );
console.log( hmm.index('name').potatoes );
console.log( hmm.index('allergens').milk );
console.log( hmm.uniqueIndex('name') );
console.log( hmm.uniqueIndex('name').potatoes );
console.log( hmm.index('allergens') );
console.log( hmm.index('allergens.0') ); //Index on the first allergy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment