Last active
August 29, 2015 14:03
-
-
Save konijn/2d2737b0f86792e27b32 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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