From c64e8d4b53aeaac4730ea1b754a8ddb5ce970db9 Mon Sep 17 00:00:00 2001 From: Timothy Jones Date: Wed, 20 Oct 2010 05:34:03 +1300 Subject: [PATCH] Added the __inArray helper to clean up code and speed up searches. --- lib/nodes.js | 24 +++++++++--------------- src/nodes.coffee | 19 +++++++++++++------ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index 097780a6..623971d9 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1478,32 +1478,25 @@ return this.array instanceof Value && this.array.isArray(); }; In.prototype.compileNode = function(o) { - var _ref2; - _ref2 = this.object.compileReference(o, { - precompile: true - }), this.obj1 = _ref2[0], this.obj2 = _ref2[1]; return this.isArray() ? this.compileOrTest(o) : this.compileLoopTest(o); }; In.prototype.compileOrTest = function(o) { - var _len, _ref2, _result, i, item, tests; + var _len, _ref2, _ref3, _result, i, item, obj1, obj2, tests; + _ref2 = this.object.compileReference(o, { + precompile: true + }), obj1 = _ref2[0], obj2 = _ref2[1]; tests = (function() { _result = []; - for (i = 0, _len = (_ref2 = this.array.base.objects).length; i < _len; i++) { - item = _ref2[i]; - _result.push("" + (i ? this.obj2 : this.obj1) + " === " + (item.compile(o))); + for (i = 0, _len = (_ref3 = this.array.base.objects).length; i < _len; i++) { + item = _ref3[i]; + _result.push("" + (i ? obj2 : obj1) + " === " + (item.compile(o))); } return _result; }).call(this); return "(" + (tests.join(' || ')) + ")"; }; In.prototype.compileLoopTest = function(o) { - var _ref2, _ref3, i, l, prefix; - _ref2 = this.array.compileReference(o, { - precompile: true - }), this.arr1 = _ref2[0], this.arr2 = _ref2[1]; - _ref3 = [o.scope.freeVariable('i'), o.scope.freeVariable('len')], i = _ref3[0], l = _ref3[1]; - prefix = this.obj1 !== this.obj2 ? this.obj1 + '; ' : ''; - return "(function(){ " + prefix + "for (var " + i + "=0, " + l + "=" + (this.arr1) + ".length; " + i + "<" + l + "; " + i + "++) { if (" + (this.arr2) + "[" + i + "] === " + (this.obj2) + ") return true; } return false; }).call(this)"; + return "" + (utility('inArray')) + "(" + (this.array.compile(o)) + ", " + (this.object.compile(o)) + ")"; }; return In; })(); @@ -1964,6 +1957,7 @@ UTILITIES = { "extends": 'function(child, parent) {\n function ctor() { this.constructor = child; }\n ctor.prototype = parent.prototype;\n child.prototype = new ctor;\n if (typeof parent.extended === "function") parent.extended(child);\n child.__super__ = parent.prototype;\n}', bind: 'function(func, context) {\n return function() { return func.apply(context, arguments); };\n}', + inArray: '(function() {\n var indexOf = Array.prototype.indexOf || function (item) {\n for (var i = this.length; i--;) if (this[i] === item) return i;\n return -1;\n }; return function(array, item) { return indexOf.call(array, item) > -1; };\n})();', hasProp: 'Object.prototype.hasOwnProperty', slice: 'Array.prototype.slice' }; diff --git a/src/nodes.coffee b/src/nodes.coffee index c2561aa6..1c53a310 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1260,19 +1260,16 @@ exports.In = class In extends Base @array instanceof Value and @array.isArray() compileNode: (o) -> - [@obj1, @obj2] = @object.compileReference o, precompile: yes if @isArray() then @compileOrTest(o) else @compileLoopTest(o) compileOrTest: (o) -> + [obj1, obj2] = @object.compileReference o, precompile: yes tests = for item, i in @array.base.objects - "#{if i then @obj2 else @obj1} === #{item.compile(o)}" + "#{if i then obj2 else obj1} === #{item.compile(o)}" "(#{tests.join(' || ')})" compileLoopTest: (o) -> - [@arr1, @arr2] = @array.compileReference o, precompile: yes - [i, l] = [o.scope.freeVariable('i'), o.scope.freeVariable('len')] - prefix = if @obj1 isnt @obj2 then @obj1 + '; ' else '' - "(function(){ #{prefix}for (var #{i}=0, #{l}=#{@arr1}.length; #{i}<#{l}; #{i}++) { if (#{@arr2}[#{i}] === #{@obj2}) return true; } return false; }).call(this)" + "#{utility 'inArray'}(#{@array.compile o}, #{@object.compile o})" #### Try @@ -1669,6 +1666,16 @@ UTILITIES = return function() { return func.apply(context, arguments); }; } ''' + + # Discover if an item is in an array. + inArray: ''' + (function() { + var indexOf = Array.prototype.indexOf || function (item) { + for (var i = this.length; i--;) if (this[i] === item) return i; + return -1; + }; return function(array, item) { return indexOf.call(array, item) > -1; }; + })(); + ''' # Shortcuts to speed up the lookup time for native functions. hasProp: 'Object.prototype.hasOwnProperty'