HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Hmm, a thoughtful library

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
hmmlibrarythoughtful

Problem

I've been writing far too many routines in JavaScript that get a record from a an object or array based off a matching property, much like jQuery does with DOM elements. Since all the good names are taken, I called it Hmm.

I went with the philosophy that if I don't need it yet, I wont provide for it.

``
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
this.data = data instanceof Object ? data : JSON.parse( 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 );
}

Solution

It's very nice. What few qualms I have are a result of me looking really hard for things to have qualms about (furrowing my brow and going "hmm", basically).

Anyway, some thoughts:

-
Your unique function relies on the assumption that there are no circular references in the object passed to JSON.stringify. It's probably a fair assumption, but an assumption nonetheless. Also, from a specification standpoint, JSON representation of objects doesn't impose or guarantee any ordering of properties. I highly doubt it'll ever be an issue anywhere, but it could mean that identical objects will have different JSON representations, and unique would thus include both those objects.

-
Similarly edge-case'y: Your instanceof usage is vulnerable to the usual cross-frame pitfalls.

-
The !~array.indexOf( value ) trick is a bit arcane. It's neat, but I don't think I've actually seen it used anywhere - except in some other code you posted :)

A === -1 comparison isn't nearly as cool, but it wouldn't cause me to go "huh?". In other words: I like it, but I wouldn't call it obvious or idiomatic.

-
That curly-brace-on-new-line style just rubs me the wrong way, but you know what you're doing, so I'll spare you the "automatic semi-colon insertion" speech :)

On a more overall note: Like jQuery, it might be useful to always return a Hmm-wrapped array, instead of only adding unique to the array returned by collect. Of course it'd be quite a different API.

Context

StackExchange Code Review Q#49152, answer score: 6

Revisions (0)

No revisions yet.