1 // Various utility methods, primary for easy of functionals programming 2 /*jslint white: false, onevar: false, plusplus: false */ 3 4 var nimbusly; 5 if (nimbusly === undefined) { nimbusly = {}; } 6 7 /** 8 * Apply a method to each member of an array 9 * 10 * @param f - A function taking a single value and returning a value 11 */ 12 Array.prototype.each = function(f) { 13 for (var i = 0; i < this.length; ++i) { 14 f(this[i], i); 15 } 16 }; 17 18 Array.prototype.find = function(match) { 19 for (var i = 0; i < this.length; ++i) { 20 if (match(this[i])) { 21 return this[i]; 22 } 23 } 24 }; 25 26 Array.prototype.map = function(f) { 27 var result = new Array(this.length); 28 for (var i = 0; i < this.length; ++i) { 29 result[i] = f(this[i]); 30 } 31 return result; 32 }; 33 34 /** 35 * Apply a method to initial and the first value of the array, then to the result and the second, and 36 * so on. For example, to sum the array, you could use: 37 * 38 * [1, 4, 7].reduce(function(a,b) { return a+b }, 0) 39 * 40 * @param op function to apply. It should take two parameters 41 * @param initial Initial value. If left out, it won't be used 42 */ 43 Array.prototype.reduce = function(op, initialValue) { 44 var result = initialValue; 45 var start = 0; 46 if (!result) { 47 if (this.length === 0) { 48 return undefined; 49 } 50 result = this[0]; 51 start = 1; 52 } 53 for (var i = start; i < this.length; ++i) { 54 result = op(result, this[i]); 55 } 56 return result; 57 }; 58 59 Object.prototype.merge_in = function(hash) { 60 for (var prop in hash) { 61 if (hash.hasOwnProperty(prop)) { 62 this[prop] = hash[prop]; 63 } 64 } 65 return this; 66 }; 67 68 Object.prototype.merge = function(hash) { 69 var result = {}; 70 result.merge_in(this).merge_in(hash); 71 return result; 72 }; 73 74 Function.prototype.curry = function() { 75 var f = this; 76 var appendArgs = function(a, b) { 77 for (var i = 0; i < b.length; ++i) { 78 a.push(b[i]); 79 } 80 return a; 81 }; 82 var concatArgs = function(a, b) { 83 return appendArgs(appendArgs([], a), b); 84 }; 85 var curriedArgs = arguments; 86 return function() { 87 return f.apply(this, concatArgs(curriedArgs, arguments)); 88 }; 89 }; 90 91 Function.prototype.andThen = function(g) { 92 var f = this; 93 return function() { f.apply(this, arguments); g.apply(this, arguments); }; 94 }; 95 96 Function.prototype.compose = function(g) { 97 var f = this; 98 return function() { return f(g.apply(this, arguments)); }; 99 }; 100 101 /** 102 * Given a function f(args.., callback), and a function g(args.., callback), f.callsback(g) 103 * will return a new function h(arg.., callback), that combines the calls to f and g. 104 */ 105 Function.prototype.callsback = function(g) { 106 toArray = function(args) { 107 var result = []; 108 for (var i = 0; i < args.length; ++i) { 109 result.push(args[i]); 110 } 111 return result; 112 }; 113 114 var f = this; 115 return function() { 116 var callback = arguments[arguments.length-1]; 117 var gCallback = function() { 118 var newArgs = toArray(arguments); 119 newArgs.push(callback); 120 g.apply(this, newArgs); 121 }; 122 var args = toArray(arguments).slice(0, -1); 123 args.push(gCallback); 124 return f.apply(this, args); 125 } 126 } 127 128 /** 129 * Generate a random integer between 0 and max-1 130 */ 131 Math.randomInt = function(limit) { 132 return Math.floor(Math.random() * limit); 133 }; 134 135 /** 136 * Method to convert a list of functions into a has to return as a prototype object 137 */ 138 nimbusly.log = function(message) { 139 // console.log(message); 140 }; 141 142 /** 143 * Converts an object and method anme into a callback that will run the method in the context to the object 144 */ 145 Function.prototype.makeCallback = function(obj) { 146 var method = this; 147 return function() { return method.apply(obj, arguments); } 148 }; 149 150