Created
December 22, 2012 14:42
-
-
Save madbook/4359133 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/** | |
* creates an array-like list of items. each item can have multiple 'terms' | |
* associated with it, and you can filter the list of items down by accessing | |
* those terms as properties of the object. To get the results of the query | |
* just end with parens, like: | |
* | |
* myObj.foo.bar() = [all objects with foo and bar terms]; | |
* | |
* passing in values into the function call will add them as values with the | |
* current query as their terms. so | |
* | |
* myObj.foo.bar(fooBarObject); | |
* | |
* adds fooBarObject with terms 'foo' and 'bar', as well as returns an array of | |
* all 'foo' and 'bar' objects (including the new one); any number of values | |
* can be passed. | |
* | |
* It also doesn't matter what order you query in | |
* | |
* myObj.foo.bar(); | |
* myObj.bar.foo(); | |
* | |
* passing in arguments when there is no query adds the arguments as new terms. | |
* These should be strings only! | |
* | |
* myObj('bat'); // adds new 'bat' term | |
* | |
* query state is saved until function is called. | |
* | |
* myObj.foo; | |
* myObj.bar(); // returns result of 'foo' and 'bar'! | |
* | |
* to clear query state, just call the function with no arguments | |
* | |
* myObj(); // returns current query and resets query state | |
* | |
* still to do! | |
* - modify terms associated with values in the list after setting | |
* could revert to returning an array of objects, but thats less cool | |
* - array-like methods (push, pop, splice, etc) | |
* - setter functions, what does myObj.foo.bar = 1; do? | |
* | |
*/ | |
function MultiDimensionalList () { | |
var terms = []; | |
var items = []; | |
var query = []; | |
var search = []; // items list filtered by query; | |
var filter = MultiDimensionalList.filter; // local reference to filter method | |
var map = MultiDimensionalList.map; // local reference to map method | |
var list = function (/* terms */) { | |
var args = Array.prototype.slice.call(arguments); | |
var i, l; | |
var item; | |
if (query.length) { | |
// add new items with current query as terms | |
for (i = 0, l = args.length; i < l; i++) { | |
item = { value: args[i], terms : query.slice() }; | |
items.push(item); | |
search.push(item); | |
} | |
} else { | |
// add new terms | |
for (i = 0, l = args.length; i < l; i++) { | |
if (terms.indexOf(args[i])===-1) { | |
terms.push(args[i]); | |
} | |
} | |
// add new property getters | |
for (i = 0, l = args.length; i < l; i++) { | |
(function (prop) { | |
Object.defineProperty(list, prop, { | |
get : function () { | |
if (query.indexOf(prop)==-1) | |
query.push(prop); | |
search = filter(search, query); | |
return list; | |
}, | |
set : function (v) { | |
// what to do here? | |
// myArray.foo.bar.js = ??? what makes sense here? full replace? | |
} | |
}); | |
})(args[i]); | |
} | |
} | |
// any time we call the list object as a function, we | |
// do the necessary work (add new things) then return | |
// the results of the current query and reset | |
var res = search.map(map); | |
query = []; | |
search = items.slice(); | |
return res; | |
}; | |
list.apply(this, Array.prototype.slice.call(arguments)); | |
return list; | |
} | |
MultiDimensionalList.filter = function (search, query) { | |
var i, l, j, k, _in; | |
var res = []; | |
for (i = 0, l = search.length; i < l; i++) { | |
_in = true; | |
for (j = 0, k = query.length; j < k; j++) { | |
if (search[i].terms.indexOf(query[j])==-1) _in = false; | |
} | |
if (_in) res.push(search[i]); | |
} | |
return res; | |
}; | |
MultiDimensionalList.map = function (item) { | |
return item.value; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment