I'm looking to lower my overhead on code like this
foo(bar(baz("hello"))) // function hell
ideally something like this
var fbb = bind(foo, bar, baz)
foo("hello")
Does this exist? Native or library?
I looked through underscore and bind.
Underscore has the compose function which will do what you want:
var composite = _.compose(foo, bar, baz);
composite('hello');
function foo(a1){
return 'foo' + a1;
}
function bar(a2){
return 'bar' + a2;
}
function baz(a3){
return 'baz' + a3;
}
alert(foo(bar(baz("hello"))));
var composite = _.compose(foo, bar, baz);
alert( composite('hello') );
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
function getCaller(first) {
var rest = Array.prototype.slice.call(arguments, 1);
return function (value) {
return rest.reduce(function (previous, next) {
return next(previous);
}, first(value));
};
}
function foo(string) {
return string + ' world!';
}
function bar(string) {
return string + ' Hi';
}
function baz(string) {
return string + ' Mom!';
}
var caller = getCaller(foo, bar, baz);
console.log(caller('Hello'));
// Prints: Hello world! Hi Mom!
var bind = function() {
var fns = Array.prototype.slice.call(arguments).reverse();
return function(value) {
for (var key in fns) {
var fn = fns[key];
console.log(fn);
value = fn(value);
}
return value;
}
}
function plusTomato(value) {
return value + "tomato";
}
function plusPear(value) {
return value + "pear";
}
var plus = bind(plusTomato, plusPear);
var y = plus("pancake"); //pankaketomatopear
console.log(y);
var x = plusTomato(plusPear("pancake")); //pankaketomatopear
console.log(x);
Related
I am trying to write a memoization function, but keep getting the following error.
Error - "TypeError: getNthFibonacciNo is not a function
at dabebimaya.js:28:38
at https://static.jsbin.com/js/prod/runner-4.1.4.min.js:1:13924
at https://static.jsbin.com/js/prod/runner-4.1.4.min.js:1:10866"
How can I find this error in my code? I have tried googling the error with no avail. Please point out any additional errors too if possible.
function memoize(fn) {
var cache = {};
if (cache[arguments[0]]!==undefined) {
return cache[arguments[0]];
}
else {
var value = fn.apply(this, arguments);
cache[arguments[0]] = value;
return value;
}
}
var getNthFibonacciNo = memoize(function(n){
//1,1,2,3,5,8,13,21,34
if(i<=2)
return 1;
var fib = [0,1,1];
for(var i=3;i<=n;i++) {
fib[i] = fib[i-2]+fib[i-1];
}
return fib[n];
});
console.log(getNthFibonacciNo(7));
Your memoize function isn't returning a function.
function memoize(fn) {
var cache = {};
return function() {
if (cache[arguments[0]]!==undefined) {
return cache[arguments[0]];
}
else {
var value = fn.apply(this, arguments);
cache[arguments[0]] = value;
return value;
}
}
}
now returns a function so that it can be called multiple times.
Usage
function test(a) {
console.log('calling test', a);
return a + 1;
}
const memoized = memoize(test);
memoized(1); // prints calling test and returns 2
memoized(1); // returns 2
memoized(2); // prints calling test and returns 3
I managed to fix my code after suggestions by AnilRedshift. Below is the fixed code.
function memoize(fn) {
var cache = {};
return function() {
var key = JSON.stringify(arguments);
if (cache[key]) {
console.log('cache used');
return cache[key];
}
else {
var value = fn.apply(this, arguments);
cache[key] = value;
console.log('cache not used');
return value;
}
};
}
var fibonacciMemoized = memoize(function(n) {
//1,1,2,3,5,8,13,21,34
if(i<=2)
return 1;
var fib = [0,1,1];
for(var i=3;i<=n;i++) {
fib[i] = fibonacciMemoized(i-2)+fibonacciMemoized(i-1);
}
return fib[n];
});
console.log(fibonacciMemoized(7));
console.log(fibonacciMemoized(9));
I have string where there may be occurrence of %[{variable}, percentage] which i want to convert to (({variable}*percentage)/100) and replace it at same location. What is best way to do it?
Example: {operation} + %[{cost}, 10] should be converted to {operation} + (({cost}*10)/100)
I tried following but it didn't work:
function Service(){
this.percentageRegx = "\%\[(.*?)]";
this.percentageVariableRegx = "\%\[(.*?)]";
this.percentageValueRegx = "\,(.*?)]";
this.getPercentageFromFormula = function (formula) {
var data = [];
try {
do {
m = self.percentageRegx.exec(formula);
if (m) {
var variableData = self.percentageVariableRegx.exec(m[1]),
percentageData = self.percentageValueRegx.exec(m[1]);
if(variableData !== null && percentageData !== null){
data.push({
string: m[1],
variable: variableData[1],
percentage: percentageData[1]
});
}
}
} while (m);
} catch (e) {}
return data;
};
/**
* Convert percentages to formula
*/
this.replacePercentageToFormula = function (formula) {
var percentages = self.getPercentageFromFormula(formula);
angular.forEach(percentages, function (percentage) {
formula.replace(percentage.string,"(("+percentage.variable+"*"+percentage.percentage+")/100)");
});
return formula;
};
}
var service = new Service();
formula = service.replacePercentageToFormula("{operation} + %[{cost}, 10]");
It giving me Uncaught SyntaxError: Invalid or unexpected token error
That's a lot of code for what seems to me like a simple one-line regex-based string replacement:
var input = "{operation} + %[{cost}, 10] {?} * %[{123}, 5]";
var output = input.replace(/%\[(\{[^}]+\}), *(\d+)\]/g, "(($1*$2)/100)");
console.log(output);
I suggest you to implement a very very basilar template engine, or, if you need for many and solid features, have a look at one existing such as HandleBars, or TwigJS.
By the way, this is a little implementation:
var Template = (function() {
function TemplateEngine() {
this._re = (function(start, end) {
start = "\\" + start.split("").join("\\");
end = "\\" + end.split("").join("\\");
return new RegExp(
"(("+ start +")(.*)("+ end +"))",
"g"
);
}).apply(this, this.separators);
}
TemplateEngine.prototype.separators = ["{{", "}}"];
TemplateEngine.prototype.map = function(str, model) {
return str
.replace(this._re,
function(matches, tpl, sStart, content, sEnd) {
return Object.keys(model).reduce(function(res, variable) {
return (
res = content.replace(variable, model[variable])
);
}, "");
}
);
}
TemplateEngine.prototype.render = function(tpl, context) {
var parsed = this.map(tpl, context), result;
try {
result = eval(parsed);
} catch(e) {
result = parsed.replace(/['"`]/g, "");
}
this._re.lastIndex = 0;
return result;
};
return new TemplateEngine();
})();
// TESTS
console.log(
Template.render("{{foo * 5}}", {foo: 2})
);
console.log(
Template.render("{{foo 'World'; }}", {foo: "Hello"})
);
NOTE: I always suggest you to use a community-trusted solution.
Good day. I need to eval expression in some object context, but the only solution I found is to create stubs for every object function:
var c = {
a : function () {
return 'a';
},
b : function () {
return 'b';
}
};
function evalInObj(c, js) {
function a() {
return c.a();
}
function b() {
return c.b();
}
return eval(js);
};
console.log(evalInObj(c, 'a() + b()'));
Show me the right way, please. Can I do it with prototype?
var C = function(id) {
this.id = id;
}
C.prototype.a = function () {
return 'a' + this.id;
}
C.prototype.b = function () {
return 'b' + this.id;
}
function evalCtx(js) {
console.log(this); // C {id: 1}
return eval(js);
}
var c1 = new C(1);
evalCtx.call(c1, 'a() + b()'); // error: a is not defined
For late-comers who are still looking for the solution of the issue (or the similar). Instead of using eval(), we can create anonymous function dynamically and evaluate the expression in the object context:
function evaluate(expression, context = {}) {
try {
// console.debug("[DEBUG] Dynamic anonymous function to be defined:\n%s", `function(${[...Object.keys(context)].join()}) {\n'use strict'; return (${expression})\n}`)
const fun = Function(...Object.keys(context), `'use strict'; return (${expression})`)
// console.debug("[DEBUG] Dynamically defined anonymous function:\n%o", fun)
const result = fun(...Object.values(context))
// console.debug("[DEBUG] Evaluation result: %o", result)
return result
} catch(error) {
if(error.message === `Unexpected token ')'`) throw SyntaxError('Unexpected token, likely at the end of expression.')
else throw error
}
}
To assert:
console.assert(evaluate('a===1 && b===2', {a: 1, b: 2}) === true)
console.assert(evaluate('a===1 && b===3', {a: 1, b: 2}) === false)
console.assert(evaluate('f()', {a: 1, f: ()=>11}) === 11)
(() =>
{
// 'use strict';
function run(expression, context = {})
{
return function ()
{
return eval(expression);
}.call(context);
}
let context = {a:{b:'Bb'}};
console.log(run('this', context)); // {a:{b:'Bb'}}
console.log(run('this.a', context)); // {b:'Bb'}
console.log(run('this.a.b', context)); // 'Bb'
console.log(run('a.b', context)); // ReferenceError: a is not defined
})();
The most notable advantage of this technique is that it work without the with keyword,
Thus even in strict mode
+function()
{
// jsut pollyfills for backward browsers...
Object.prototype.keys || (Object.defineProperty(Object.prototype, 'keys', {value: function ()
{
var result = []; for (var key in this) result.push(key); return result;
}}));
Object.prototype.entries || (Object.defineProperty(Object.prototype, 'entries', {value: function ()
{
var result = []; for (var key in this) result.push([key, this[key]]); return result;
}}));
// here the magic...
function run(expression, context)
{
var variables = {};
(context instanceof Object) && context.entries().forEach(function(entry)
{
entry[0].match(/^[a-z_$][a-z0-9_$]*$/) && (variables[entry[0]] = entry[1]);
});
return (new Function('return function(' + variables.keys().join(', ') + ') { return ' + expression + '; }'))()// first get the synthetic function
.apply(context, variables.entries().map(function(entry) { return entry[1]; }));
}
var output = run("a + '#' + b", {a: 'Aa', b: 'Bb', 0: 'Zero'});
console.log(output); // Aa#Bb
}();
function runScript(ctx, js){ with(ctx){ return eval(js); }}
closed. thanks all
function modifyFunction(f) {
return function () {
var returnValue = f.apply(this, arguments);
console.log(returnValue);
if (returnValue == undefined) {
return this;
} else {
return returnValue;
}
};
}
function modifyMethod(o, m) {
if (o.hasOwnProperty(m)) {
if (o[m] instanceof Function) {
o[m] = modifyFunction(m);
}
}
}
var o = {
num: 0,
add: function (x) {
return this.num += x;
},
sub: function (x) {
return this.num -= x;
}
};
modifyMethod(o, "add");
o.add(2).add(4);
console.log(o.num); // o.num = 6
modifyMethod(o, "sub");
o.sub(1).add(3).sub(5);
console.log(o.num); // o.num = 3
How would I make it so that in modifyMethod function inside of the "if(o[m] instanceof Function)" would be equal to what returns by the modifyFunction function, when sending it o[m]? I am trying to make it so that it is chainable, yet I am having a very difficult time getting my head around this.
To make o.add(2).add(4); equal to o.add(2); o.add(4); We can observe that what o.add(2) returns should be o. So your modifyFunction should return a function that :
call the passed in function with given parameters.
Return the caller.
So instead of return that returnValue(which is o.num, a number), you should always return this.
Another point is that in your modifyMethod, after you checked if o[m] is a function, you should pass in that function, not m which is just the key. So it should be o[m] = modifyFunction(o[m]);
function modifyFunction(f) {
return function () {
var returnValue = f.apply(this, arguments);
// Return the object that call this function,
// so it becomes chainable.
return this;
};
}
function modifyMethod(o, m) {
if (o.hasOwnProperty(m)) {
if (o[m] instanceof Function) {
// Pass o[m], not m, m is a string.
o[m] = modifyFunction(o[m]);
}
}
}
var o = {
num: 0,
add: function (x) {
return this.num += x;
},
sub: function (x) {
return this.num -= x;
}
};
modifyMethod(o, "add");
o.add(2).add(4);
console.log(o.num); // o.num = 6
modifyMethod(o, "sub");
o.sub(1).add(3).sub(5);
console.log(o.num); // o.num = 3
Is there a more succinct way to express this than three distinct, procedural operations? Something more object notation-like, or at least all within the body of the Name function?
Problem:
function Name(first, last) {
this.first = first;
this.last = last;
}
Name.prototype = new String;
Name.prototype.toString = function() {
return this.last + ', ' + this.first;
};
Test:
console.log(new Name("jimmy", "dean").toString())
console.log(new Name() instanceof Name);
console.log(new Name() instanceof String);
console.log(new Name() instanceof Object);
console.log(Name.prototype.toString.call(new Name('jimmy', 'dean')));
console.log(Name.prototype.toString.call({
first: 'jimmy',
last: 'dean'
}));
Expected output:
< "dean, jimmy"
< true
< true
< true
< "dean, jimmy"
< "dean, jimmy"
Example
function Name(first, last) {
this.partFirst = first;
this.partLast = last;
this.valueOf = this.toString = function() {
return this.partLast + ', ' + this.partFirst;
}
}
Name.prototype = new String();
Here's how I do it:
function subclass(constructor, superConstructor) {
function surrogateConstructor() { }
surrogateConstructor.prototype = superConstructor.prototype;
var prototypeObject = new surrogateConstructor();
prototypeObject.constructor = constructor;
constructor.prototype = prototypeObject;
}
/* Base object */
function BaseItem() {
this.type = 'baseitem';
this.obj = null;
}
BaseItem.prototype.render = function() {
return "foo";
}
/* Sub class */
function InteractionArea() {
BaseItem.call(this);
this.type = 'interactionarea'
this.obj = document.createElement('div')
}
subclass(InteractionArea, BaseItem);
//here come the overrides
InteractionArea.prototype.render = function() {
return "foobar";
}
InteractionArea.prototype.render2 = function() {
return "foobar";
}
/* Sub-sub class */
function InteractionArea2() {
InteractionArea.call(this);
this.type = 'interactionarea2';
this.obj = false;
}
subclass(InteractionArea2, InteractionArea);
InteractionArea2.prototype.render = function() {
return "bar";
}
Sure. Use Object.create.
var Name = Object.create(String.prototype, {
toString: { value: function _toString() {
return this.partLast + ', ' + this.partFirst;
} },
constructor: { value: function _constructor(first, last) {
this.partFirst = first;
this.partLast = last;
return this;
} }
});
var name = Object.create(Name).constructor("foo", "bar");
Now ES5 is a bit ugly, so you can use some mechanism for ES5 OO sugar, let's take pd as an example:
var Name = pd.make(String.prototype, {
toString: function _toString() {
return this.partLast + ', ' + this.partFirst;
},
constructor: function (first, last) {
this.partFirst = first;
this.partLast = last;
},
beget: pd.Base.beget
});
console.log(Name.beget("jimmy", "dean").toString())
console.log(Name.isPrototypeOf(Name.beget()));
console.log(String.prototype.isPrototypeOf(Name.beget()));
console.log(Object.prototype.isPrototypeOf(Name.beget()));
console.log(Name.toString.call(Name.beget('jimmy', 'dean')));
console.log(Name.toString.call({
partFirst: 'jimmy',
partLast: 'dean'
}));
Of course output is as expected Live Example