Comparing version 0.2.3 to 0.2.4
{ | ||
"name": "sift", | ||
"description": "mongodb query style array filtering", | ||
"version": "0.2.3", | ||
"version": "0.2.4", | ||
"repository": {}, | ||
@@ -13,2 +13,4 @@ "engines": {}, | ||
"expect.js": "0.2.x", | ||
"jscs": "^1.11.0", | ||
"jshint": "^2.6.0", | ||
"karma": "0.8.x", | ||
@@ -23,4 +25,4 @@ "mocha": "1.9.x", | ||
"scripts": { | ||
"test": "mocha ./test" | ||
"test": "make lint test-node" | ||
} | ||
} |
180
sift.js
@@ -10,15 +10,13 @@ /* | ||
(function() { | ||
/** | ||
*/ | ||
var _convertDotToSubObject = function(keyParts, value) { | ||
function _convertDotToSubObject(keyParts, value) { | ||
var subObject = {}, | ||
currentValue = subObject; | ||
var subObject = {}; | ||
var currentValue = subObject; | ||
for(var i = 0, n = keyParts.length - 1; i < n; i++) { | ||
for (var i = 0, n = keyParts.length - 1; i < n; i++) { | ||
currentValue = currentValue[keyParts[i]] = {}; | ||
@@ -35,3 +33,3 @@ } | ||
var _queryParser = new (function() { | ||
function QueryParser() { | ||
@@ -44,12 +42,12 @@ /** | ||
var exprs = statement.exprs, | ||
priority = 0; | ||
var exprs = statement.exprs; | ||
var priority = 0; | ||
//generally, expressions are ordered from least efficient, to most efficient. | ||
for(var i = 0, n = exprs.length; i < n; i++) { | ||
for (var i = 0, n = exprs.length; i < n; i++) { | ||
var expr = exprs[i], | ||
p; | ||
var expr = exprs[i]; | ||
var p; | ||
if(!~(p = expr.e(expr.v, _comparable(data), data))) return -1; | ||
if (!~(p = expr.e(expr.v, _comparable(data), data))) return -1; | ||
@@ -60,7 +58,5 @@ priority += p; | ||
return priority; | ||
} | ||
}; | ||
/** | ||
@@ -73,3 +69,3 @@ * parses a statement into something evaluable | ||
//fixes sift(null, []) issue | ||
if(!statement) statement = { $eq: statement }; | ||
if (!statement) statement = { $eq: statement }; | ||
@@ -79,5 +75,5 @@ var testers = []; | ||
//if the statement is an object, then we're looking at something like: { key: match } | ||
if(Object.prototype.toString.call(statement) === "[object Object]") { | ||
if (Object.prototype.toString.call(statement) === "[object Object]") { | ||
for(var k in statement) { | ||
for (var k in statement) { | ||
@@ -90,6 +86,6 @@ //find the apropriate operator. If one doesn't exist and the key does not start | ||
operator = k; | ||
} else if (k.substr(0, 1) !== '$') { | ||
operator = '$trav'; | ||
} else if (k.substr(0, 1) !== "$") { | ||
operator = "$trav"; | ||
} else { | ||
throw new Error('Unknown operator.'); | ||
throw new Error("Unknown operator."); | ||
} | ||
@@ -104,7 +100,6 @@ | ||
//if we're working with a traversable operator, then set the expr value | ||
if(TRAV_OP[operator]) { | ||
if (TRAV_OP[operator]) { | ||
//using dot notation? convert into a sub-object | ||
if(~k.indexOf(".")) { | ||
if (~k.indexOf(".")) { | ||
var keyParts = k.split("."); | ||
@@ -117,7 +112,7 @@ k = keyParts.shift(); //we're using the first key, so remove it | ||
//*if* the value is an array, then we're dealing with something like: $or, $and | ||
if(value instanceof Array) { | ||
if (value instanceof Array) { | ||
exprValue = []; | ||
for(var i = value.length; i--;) { | ||
for (var i = value.length; i--;) { | ||
exprValue.push(parse(value[i])); | ||
@@ -133,9 +128,7 @@ } | ||
testers.push(_getExpr(operator, k, exprValue)); | ||
} | ||
//otherwise we're comparing a particular value, so set to eq | ||
} else { | ||
testers.push(_getExpr('$eq', k, statement)); | ||
testers.push(_getExpr("$eq", key, statement)); | ||
} | ||
@@ -155,6 +148,4 @@ | ||
return stmt; | ||
}; | ||
} | ||
//traversable statements | ||
@@ -169,5 +160,4 @@ var TRAV_OP = this.traversable = { | ||
function _comparable(value) { | ||
if(value instanceof Date) { | ||
if (value instanceof Date) { | ||
return value.getTime(); | ||
@@ -227,3 +217,2 @@ } else { | ||
/** | ||
@@ -233,3 +222,3 @@ */ | ||
$exists: function(a, b) { | ||
return btop(a === (b != null)) | ||
return btop(a === (b != null)); | ||
}, | ||
@@ -243,6 +232,6 @@ | ||
//intersecting an array | ||
if(b instanceof Array) { | ||
if (b instanceof Array) { | ||
for(var i = b.length; i--;) { | ||
if(~a.indexOf(b[i])) return i; | ||
for (var i = b.length; i--;) { | ||
if (~a.indexOf(b[i])) return i; | ||
} | ||
@@ -254,3 +243,2 @@ | ||
return -1; | ||
@@ -263,3 +251,3 @@ }, | ||
$not: function(a, b) { | ||
if(!a.test) throw new Error("$not test should include an expression, not a value. Use $ne instead."); | ||
if (!a.test) throw new Error("$not test should include an expression, not a value. Use $ne instead."); | ||
return btop(!a.test(b)); | ||
@@ -280,3 +268,2 @@ }, | ||
$nin: function(a, b) { | ||
@@ -298,6 +285,6 @@ return ~_testers.$in(a, b) ? -1 : 0; | ||
if (!b) b = []; | ||
for(var i = a.length; i--;) { | ||
for (var i = a.length; i--;) { | ||
var a1 = a[i]; | ||
var indexInB = ~b.indexOf(a1); | ||
if(!indexInB) return -1; | ||
if (!indexInB) return -1; | ||
} | ||
@@ -320,6 +307,7 @@ | ||
var i = a.length, p, n = i; | ||
var i = a.length; | ||
var n = i; | ||
for(; i--;) { | ||
if(~priority(a[i], b)) { | ||
for (; i--;) { | ||
if (~priority(a[i], b)) { | ||
return i; | ||
@@ -329,3 +317,3 @@ } | ||
return btop(n == 0); | ||
return btop(n === 0); | ||
}, | ||
@@ -338,6 +326,6 @@ | ||
var i = a.length, n = i; | ||
var i = a.length; | ||
for(; i--;) { | ||
if(~priority(a[i], b)) { | ||
for (; i--;) { | ||
if (~priority(a[i], b)) { | ||
return -1; | ||
@@ -355,4 +343,4 @@ } | ||
for(var i = a.length; i--;) { | ||
if(!~priority(a[i], b)) { | ||
for (var i = a.length; i--;) { | ||
if (!~priority(a[i], b)) { | ||
return -1; | ||
@@ -370,9 +358,7 @@ } | ||
if (b instanceof Array) { | ||
if(b instanceof Array) { | ||
for(var i = b.length; i--;) { | ||
for (var i = b.length; i--;) { | ||
var subb = b[i]; | ||
if(subb[a.k] && ~priority(a, subb[a.k])) return i; | ||
if (subb[a.k] && ~priority(a, subb[a.k])) return i; | ||
} | ||
@@ -395,6 +381,4 @@ | ||
} | ||
}; | ||
} | ||
var _prepare = { | ||
@@ -409,3 +393,3 @@ | ||
if(a instanceof RegExp) { | ||
if (a instanceof RegExp) { | ||
return a; | ||
@@ -417,3 +401,3 @@ } else if (a instanceof Function) { | ||
fn = function(b) { | ||
if(b instanceof Array) { | ||
if (b instanceof Array) { | ||
return ~b.indexOf(a); | ||
@@ -423,3 +407,3 @@ } else { | ||
} | ||
} | ||
}; | ||
} | ||
@@ -429,4 +413,3 @@ | ||
test: fn | ||
} | ||
}; | ||
}, | ||
@@ -438,10 +421,8 @@ | ||
$ne: function(a) { | ||
return _prepare.$eq(a); | ||
return _prepare.$eq(a); | ||
} | ||
}; | ||
function _getExpr(type, key, value) { | ||
var _getExpr = function(type, key, value) { | ||
var v = _comparable(value); | ||
@@ -460,11 +441,10 @@ | ||
}; | ||
} | ||
} | ||
})(); | ||
var _queryParser = new QueryParser(); | ||
var getSelector = function(selector) { | ||
if(!selector) { | ||
if (!selector) { | ||
@@ -475,4 +455,3 @@ return function(value) { | ||
} else | ||
if(typeof selector == 'function') { | ||
} else if (typeof selector == "function") { | ||
return selector; | ||
@@ -482,3 +461,3 @@ } | ||
throw new Error("Unknown sift selector " + selector); | ||
} | ||
}; | ||
@@ -493,7 +472,10 @@ var sifter = function(query, selector) { | ||
var sifted = [], results = [], testValue, value, priority; | ||
var sifted = []; | ||
var testValue; | ||
var value; | ||
var priority; | ||
//I'll typically start from the end, but in this case we need to keep the order | ||
//of the array the same. | ||
for(var i = 0, n = target.length; i < n; i++) { | ||
for (var i = 0, n = target.length; i < n; i++) { | ||
@@ -504,3 +486,3 @@ value = target[i]; | ||
//priority = -1? it's not something we can use. | ||
if(!~(priority = filter.priority(testValue))) continue; | ||
if (!~(priority = filter.priority(testValue))) continue; | ||
@@ -511,3 +493,3 @@ sifted.push(value); | ||
return sifted; | ||
} | ||
}; | ||
@@ -520,5 +502,4 @@ //set the test function incase the sifter isn't needed | ||
return self; | ||
} | ||
}; | ||
/** | ||
@@ -534,3 +515,3 @@ * sifts the given function | ||
//must be an array | ||
if(typeof target != "object") { | ||
if (typeof target != "object") { | ||
rawSelector = target; | ||
@@ -540,24 +521,21 @@ target = void 0; | ||
var sft = sifter(query, getSelector(rawSelector)); | ||
//target given? sift through it and return the filtered result | ||
if(target) return sft(target); | ||
if (target) return sft(target); | ||
//otherwise return the sifter func | ||
return sft; | ||
}; | ||
} | ||
sift.use = function(options) { | ||
if(options.operators) sift.useOperators(options.operators); | ||
if (options.operators) sift.useOperators(options.operators); | ||
if (typeof options === "function") options(sift); | ||
} | ||
}; | ||
sift.useOperators = function(operators) { | ||
for(var key in operators) { | ||
for (var key in operators) { | ||
sift.useOperator(key, operators[key]); | ||
} | ||
} | ||
}; | ||
@@ -568,3 +546,3 @@ sift.useOperator = function(operator, optionsOrFn) { | ||
if(typeof optionsOrFn == "object") { | ||
if (typeof optionsOrFn == "object") { | ||
options = optionsOrFn; | ||
@@ -575,14 +553,12 @@ } else { | ||
var key = "$" + operator; | ||
_queryParser.testers[key] = options.test; | ||
if(options.traversable || options.traverse) { | ||
if (options.traversable || options.traverse) { | ||
_queryParser.traversable[key] = true; | ||
} | ||
} | ||
}; | ||
//node.js? | ||
if((typeof module != 'undefined') && (typeof module.exports != 'undefined')) { | ||
if ((typeof module != "undefined") && (typeof module.exports != "undefined")) { | ||
module.exports = sift; | ||
@@ -592,7 +568,5 @@ } else | ||
//browser? | ||
if(typeof window != 'undefined') { | ||
if (typeof window != "undefined") { | ||
window.sift = sift; | ||
} | ||
})(); | ||
@@ -1,1 +0,1 @@ | ||
!function(){var r=function(r,n){for(var t={},e=t,o=0,i=r.length-1;i>o;o++)e=e[r[o]]={};return e[r[o]]=n,t},n=new function(){function n(r){return r instanceof Date?r.getTime():r}function t(r){return r?0:-1}var e=this.priority=function(r,t){for(var e=r.exprs,o=0,i=0,u=e.length;u>i;i++){var f,s=e[i];if(!~(f=s.e(s.v,n(t),t)))return-1;o+=f}return o},o=this.parse=function(n,t){n||(n={$eq:n});var f=[];if("[object Object]"===Object.prototype.toString.call(n))for(var a in n){var c;if(u[a])c=a;else{if("$"===a.substr(0,1))throw new Error("Unknown operator.");c="$trav"}var v=n[a],p=v;if(i[c]){if(~a.indexOf(".")){var $=a.split(".");a=$.shift(),p=v=r($,v)}if(v instanceof Array){p=[];for(var l=v.length;l--;)p.push(o(v[l]))}else p=o(v,a)}f.push(s(c,a,p))}else f.push(s("$eq",a,n));var d={exprs:f,k:t,test:function(r){return!!~d.priority(r)},priority:function(r){return e(d,r)}};return d},i=this.traversable={$and:!0,$or:!0,$nor:!0,$trav:!0,$not:!0},u=this.testers={$eq:function(r,n){return t(r.test(n))},$ne:function(r,n){return t(!r.test(n))},$lt:function(r,n){return t(r>n)},$gt:function(r,n){return t(n>r)},$lte:function(r,n){return t(r>=n)},$gte:function(r,n){return t(n>=r)},$exists:function(r,n){return t(r===(null!=n))},$in:function(r,n){if(!(n instanceof Array))return t(~r.indexOf(n));for(var e=n.length;e--;)if(~r.indexOf(n[e]))return e;return-1},$not:function(r,n){if(!r.test)throw new Error("$not test should include an expression, not a value. Use $ne instead.");return t(!r.test(n))},$type:function(r,n,e){return e?t(e instanceof r||e.constructor==r):-1},$nin:function(r,n){return~u.$in(r,n)?-1:0},$mod:function(r,n){return n%r[0]==r[1]?0:-1},$all:function(r,n){n||(n=[]);for(var t=r.length;t--;){var e=r[t],o=~n.indexOf(e);if(!o)return-1}return 0},$size:function(r,n){return n?t(r==n.length):-1},$or:function(r,n){for(var o=r.length,i=o;o--;)if(~e(r[o],n))return o;return t(0==i)},$nor:function(r,n){for(var t=r.length;t--;)if(~e(r[t],n))return-1;return 0},$and:function(r,n){for(var t=r.length;t--;)if(!~e(r[t],n))return-1;return 0},$trav:function(r,n){if(n instanceof Array){for(var t=n.length;t--;){var o=n[t];if(o[r.k]&&~e(r,o[r.k]))return t}return-1}return e(r,n?n[r.k]:void 0)},$regex:function(r,n){var t=new RegExp(r);return t.test(n)?0:-1}},f={$eq:function(r){var n;return r instanceof RegExp?r:(n=r instanceof Function?r:function(n){return n instanceof Array?~n.indexOf(r):r==n},{test:n})},$ne:function(r){return f.$eq(r)}},s=function(r,t,e){var o=n(e);return{k:t,v:f[r]?f[r](o):o,e:u[r]}}},t=function(r){if(!r)return function(r){return r};if("function"==typeof r)return r;throw new Error("Unknown sift selector "+r)},e=function(r,t){var e=n.parse(r),o=function(r){for(var n,o,i,u=[],f=0,s=r.length;s>f;f++)o=r[f],n=t(o),~(i=e.priority(n))&&u.push(o);return u};return o.test=e.test,o.score=e.priority,o.query=r,o},o=function(r,n,o){"object"!=typeof n&&(o=n,n=void 0);var i=e(r,t(o));return n?i(n):i};o.use=function(r){r.operators&&o.useOperators(r.operators),"function"==typeof r&&r(o)},o.useOperators=function(r){for(var n in r)o.useOperator(n,r[n])},o.useOperator=function(r,t){var e={};e="object"==typeof t?t:{test:t};var o="$"+r;n.testers[o]=e.test,(e.traversable||e.traverse)&&(n.traversable[o]=!0)},"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=o:"undefined"!=typeof window&&(window.sift=o)}(); | ||
!function(){function r(r,n){for(var t={},e=t,o=0,i=r.length-1;i>o;o++)e=e[r[o]]={};return e[r[o]]=n,t}function n(){function n(r){return r instanceof Date?r.getTime():r}function t(r){return r?0:-1}function e(r,t,e){var o=n(e);return{k:t,v:s[r]?s[r](o):o,e:f[r]}}var o=this.priority=function(r,t){for(var e=r.exprs,o=0,i=0,u=e.length;u>i;i++){var f,s=e[i];if(!~(f=s.e(s.v,n(t),t)))return-1;o+=f}return o},i=this.parse=function(n,t){n||(n={$eq:n});var s=[];if("[object Object]"===Object.prototype.toString.call(n))for(var a in n){var c;if(f[a])c=a;else{if("$"===a.substr(0,1))throw new Error("Unknown operator.");c="$trav"}var v=n[a],p=v;if(u[c]){if(~a.indexOf(".")){var $=a.split(".");a=$.shift(),p=v=r($,v)}if(v instanceof Array){p=[];for(var l=v.length;l--;)p.push(i(v[l]))}else p=i(v,a)}s.push(e(c,a,p))}else s.push(e("$eq",t,n));var d={exprs:s,k:t,test:function(r){return!!~d.priority(r)},priority:function(r){return o(d,r)}};return d},u=this.traversable={$and:!0,$or:!0,$nor:!0,$trav:!0,$not:!0},f=this.testers={$eq:function(r,n){return t(r.test(n))},$ne:function(r,n){return t(!r.test(n))},$lt:function(r,n){return t(r>n)},$gt:function(r,n){return t(n>r)},$lte:function(r,n){return t(r>=n)},$gte:function(r,n){return t(n>=r)},$exists:function(r,n){return t(r===(null!=n))},$in:function(r,n){if(!(n instanceof Array))return t(~r.indexOf(n));for(var e=n.length;e--;)if(~r.indexOf(n[e]))return e;return-1},$not:function(r,n){if(!r.test)throw new Error("$not test should include an expression, not a value. Use $ne instead.");return t(!r.test(n))},$type:function(r,n,e){return e?t(e instanceof r||e.constructor==r):-1},$nin:function(r,n){return~f.$in(r,n)?-1:0},$mod:function(r,n){return n%r[0]==r[1]?0:-1},$all:function(r,n){n||(n=[]);for(var t=r.length;t--;){var e=r[t],o=~n.indexOf(e);if(!o)return-1}return 0},$size:function(r,n){return n?t(r==n.length):-1},$or:function(r,n){for(var e=r.length,i=e;e--;)if(~o(r[e],n))return e;return t(0===i)},$nor:function(r,n){for(var t=r.length;t--;)if(~o(r[t],n))return-1;return 0},$and:function(r,n){for(var t=r.length;t--;)if(!~o(r[t],n))return-1;return 0},$trav:function(r,n){if(n instanceof Array){for(var t=n.length;t--;){var e=n[t];if(e[r.k]&&~o(r,e[r.k]))return t}return-1}return o(r,n?n[r.k]:void 0)},$regex:function(r,n){var t=new RegExp(r);return t.test(n)?0:-1}},s={$eq:function(r){var n;return r instanceof RegExp?r:(n=r instanceof Function?r:function(n){return n instanceof Array?~n.indexOf(r):r==n},{test:n})},$ne:function(r){return s.$eq(r)}}}var t=new n,e=function(r){if(!r)return function(r){return r};if("function"==typeof r)return r;throw new Error("Unknown sift selector "+r)},o=function(r,n){var e=t.parse(r),o=function(r){for(var t,o,i,u=[],f=0,s=r.length;s>f;f++)o=r[f],t=n(o),~(i=e.priority(t))&&u.push(o);return u};return o.test=e.test,o.score=e.priority,o.query=r,o},i=function(r,n,t){"object"!=typeof n&&(t=n,n=void 0);var i=o(r,e(t));return n?i(n):i};i.use=function(r){r.operators&&i.useOperators(r.operators),"function"==typeof r&&r(i)},i.useOperators=function(r){for(var n in r)i.useOperator(n,r[n])},i.useOperator=function(r,n){var e={};e="object"==typeof n?n:{test:n};var o="$"+r;t.testers[o]=e.test,(e.traversable||e.traverse)&&(t.traversable[o]=!0)},"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=i:"undefined"!=typeof window&&(window.sift=i)}(); |
Sorry, the diff of this file is not supported yet
42171
24
1044
12