JavaScript - shorten math function - javascript

function randomize() {
var ra = Math.floor(Math.random()*ar.length=4);
document.getElementById('es').innerHTML = ar[ra];
}
Is there a way to short this code even more than it is? The reason why is because I'm going to be using this code a lot in other projects and objects and I cannot just call it inside like this: randomize(); because I have diffrent arrays.

function randomize() {document.getElementById('es').innerHTML = ar[Math.floor(Math.random()*ar.length)];}
But you wanted to use it more without a function call:
function $(id) {
return document.getElementById(id);
}
function randomize() {
$('es').innerHTML = ar[Math.floor(Math.random()*ar.length)];
}
And instead of Math.floor, you can use ~~ for a microscopical faster diffrence.
This saves some space and time if you are going to use it more. But if only one time, use the first example.

Without knowing what, precisely, you're doing, I'd suggest passing the relevant arguments into the function as parameters:
function randomize(el, array){
if (!el || !array){
return false;
}
else {
var ra = Math.floor(Math.random() * array.length=4);
// please note that I don't understand what's happening in the above line
// and suspect, quite strongly, that the '=4' was a typo. Correct as necessary
el.innerHTML = ar[ra];
}
}
// call:
randomize(document.getElementById('es'), ['1','2']);
/* or:
var el = document.getElementById('es'),
array = ['one','two'];
randomize(el,array);

Related

I'm trying to rewrite memoize in javascript (for underscore), can someone explain this?

I know that the purpose of memoize is to cache values so code can be run faster by not having to re-calculate the same answer everytime. My issue stems from returning a function (i think). The google chrome debugger isn't that useful for me here because everytime I try to run this memoize function, it just goes from the argus variable (on line 4 i believe) all the way down to the semi-colon. Furthermore, result always returns an empty object instead of storing a value in result.
I start by defining a function:
function add(a,b){
return a+b;
}
This is my attempt at the memoize function:
_.memoize = function(func) {
var result = {};
var flag = 0;
var argus = Array.prototype.slice.call(arguments)
return function() {
if(result[key] === arguments){
flag = 1
}
else if(flag = 0){
result[argus] = func.apply(this, argus);
}
return result[argus];
};
};
I'd call memoize by doing _.memoize(add(2,5)) but the result doesn't get stored in the result object.
Am I even close to getting this memoize function working properly? Any guidance you guys can give here would be appreciated.
The biggest point you're missing is that _.memoize is called on the function first, and it returns a new function. You are calling it on the result of a function call (which is the number 7 in this case).
In order to get it to work, you need to rearrange a few things.
Also note that it's not wise to try to use an array itself as the index to an object. One approach to get around that would be to convert the arguments array to JSON and use that as the index on the results object:
function add(a, b) {
console.log('Called add(' + a + ', ' + b + ')');
return a + b;
}
var _ = {};
_.memoize = function(func) {
var results = {};
return function() {
var args = Array.prototype.slice.call(arguments);
var key = JSON.stringify(args);
if (!(key in results)) {
results[key] = func.apply(this, args);
}
return results[key];
};
};
var madd = _.memoize(add);
console.log(madd(2, 4));
console.log(madd(9, 7));
console.log(madd(2, 4));

Javascript, factorial , too difficult

var fact = (function(){
var cache = {'0': 1};
var func = function(n){
var result = 0;
if(typeof(cache[n]) === 'number'){
result = cache[n];
}
else{
result = cache[n] = n * func(n-1);
}
return result;
}
return func;
})();
console.log(fact(5)); //120
The code is this.
I can't understand this code, wholly.
It's look like add cache, and add cache
but how does this work?
Don't we need for loop to add cache?
also, return func; <- what's is this?
please explain wholly
The code is more complex than is needed. The cache array isn't being used as cache; it's being used as a means of hardcoding the fact that the factorial of 0 is 1. The recursion loop doesn't need to add to the cache, but if the extra line to do so were added, then the array would really function as a cache, and it would provide performance improvements on subsequent calls to the function.

JS Function With Two Parentheses and Two Params

I'm trying to understand how a function works that is run with two parentheses and two parameters. Like so:
add(10)(10); // returns 20
I know how to write one that takes two params like so:
function add(a, b) {
return a + b;
}
add(10,10); // returns 20
How could I alter that function so it could be run with one set of parameters, or two, and produce the same result?
Any help is appreciated. Literally scratching my head over this.
Thanks in advance!
How could I alter that function so it could be run with one set of parameters, or two, and produce the same result?
You can almost do that, but I'm struggling to think of a good reason to.
Here's how: You detect how many arguments your function has received and, if it's received only one, you return a function instead of a number — and have that function add in the second number if it gets called:
function add(a,b) {
if (arguments.length === 1) {
return function(b2) { // You could call this arg `b` as well if you like,
return a + b2; // it would shadow (hide, supercede) the one above
};
}
return a + b;
}
console.log(add(10, 10)); // 20
console.log(add(10)(10)); // 20
I said "almost" above because just because the add function received only one argument, that doesn't guarantee that the caller is going to call the result. They could write:
var x = add(10);
...and never call the function that x now refers to.
Welcome to the wonderful world of first order functions
In JavaScript, a function can return a function since a function is just another object. A simple implementation is something like:
function add(x){
return function addOther(y){
return x + y;
};
}
This is possible because of closures and first order functions.
This also lets you do partial application, libraries like Ramda utilize this to great extent.
var addThree = add(3)
addThree(5); // 8
To extend what both T. J. Crowder and Benjamin Gruenbaum said, libraries like Ramda (disclosure: I'm one of the authors) allow you to convert a simple function like this:
function add(a, b) {
return a + b;
}
into the style under discussion by wrapping it in a call to a curry function:
var add = R.curry(function add(a, b) {
return a + b;
});
add(3, 5); //=> 8
add(3)(5); //=> 8
var add3 = add(3);
add3(5); //=> 8
The best article I know on this subject is Hugh Jackson's Why Curry Helps. I wrote a more detailed one at Favoring Curry.
Update
Here is a version of curry somewhat simpler than the one in Ramda. It would do the above and quite a bit more, but doesn't do some of the things that Ramda does with placeholder values:
// here is a function that takes a function and returns a curried version
// of it, that is, a version that performs the sort of partial application
// you describe.
var curry = function(fn) {
// first, we detect how many arguments the function has.
var fnArity = fn.length;
var partialApply = function(args) {
// now, let's create a function that's curried
return function () {
// collect the previous args as the partial, and add the new
// ones you just received
var newArgs = (args || []).concat([].slice.call(arguments, 0));
// if we have "enough" arguments, we don't need any more partial
// application and we can call the function.
if (newArgs.length >= fnArity) {
return fn.apply(this, newArgs);
} else { // else we return a partially applied version
return partialApply(newArgs);
}
};
};
return partialApply([]); // a function is itself partially applied with 0 args
};
function add() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
function total() {
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return total;
}
total.toString = function () { return sum };
return total;
}
This will work for any no of arguments and parentheses.
https://medium.com/#imdebasispanda/super-function-with-closure-86a58a9a980b

Proper syntax to return variable and use it again (javascript)

I have this very simple thing, that doesn't work. What is happening? According to the tutorials that I have read, this should output 4...
function sum(a,b) {
var result = a + b;
return result;
}
sum(2,2);
var test = sum();
alert(test); // shouldn't this return "4"?
Link to the JSFiddle
function sum(a,b) {
var result = a + b;
return result;
}
var test = sum(2,2);
alert(test);
Change this:
sum(2,2);
var test = sum();
To this:
var test = sum(2,2);
The first code isn't technically wrong it just isn't doing what you're trying to do. You're calling the sum function with the appropriate values but never setting it's return value to any variable so it just gets thrown away. You seem to be under the impression that the value will "stick" to the function and this isn't the case. (Some BASIC languages can make it seem this way though. Perhaps that's where your misconception is coming from.)
Your second call is essentially the equivalent of
var test = sum(null, null);
and when you concatenate two null values you get null again.

Wrapping a function in Javascript / jQuery

If I have an arbitrary function myFunc, what I'm aiming to do is replace this function with a wrapped call that runs code before and after it executes, e.g.
// note: psuedo-javascript
var beforeExecute = function() { ... }
var afterExecute = function() { ... }
myFunc = wrap(myFunc, beforeExecute, afterExecute);
However, I don't have an implementation of the required wrap function. Is there anything that already exists in jQuery like this (I've had a good look through the docs but cannot see anything)? Alternatively does anybody know of a good implementation of this because I suspect that there are a bunch of edge cases that I'll miss if I try to write it myself?
(BTW - the reason for this is to do some automatic instrumentation of functions because we do a lot of work on closed devices where Javascript profilers etc. are not available. If there's a better way than this then I'd appreciate answers along those lines too.)
Here’s a wrap function which will call the before and after functions with the exact same arguments and, if supplied, the same value for this:
var wrap = function (functionToWrap, before, after, thisObject) {
return function () {
var args = Array.prototype.slice.call(arguments),
result;
if (before) before.apply(thisObject || this, args);
result = functionToWrap.apply(thisObject || this, args);
if (after) after.apply(thisObject || this, args);
return result;
};
};
myFunc = wrap(myFunc, beforeExecute, afterExecute);
The accepted implementation does not provide an option to call wrapped (original) function conditionally.
Here is a better way to wrap and unwrap a method:
/*
Replaces sMethodName method of oContext with a function which calls the wrapper
with it's list of parameters prepended by a reference to wrapped (original) function.
This provides convenience of allowing conditional calls of the
original function within the wrapper,
unlike a common implementation that supplies "before" and "after"
cross cutting concerns as two separate methods.
wrap() stores a reference to original (unwrapped) function for
subsequent unwrap() calls.
Example:
=========================================
var o = {
test: function(sText) { return sText; }
}
wrap('test', o, function(fOriginal, sText) {
return 'before ' + fOriginal(sText) + ' after';
});
o.test('mytext') // returns: "before mytext after"
unwrap('test', o);
o.test('mytext') // returns: "mytext"
=========================================
*/
function wrap(sMethodName, oContext, fWrapper, oWrapperContext) {
var fOriginal = oContext[sMethodName];
oContext[sMethodName] = function () {
var a = Array.prototype.slice.call(arguments);
a.unshift(fOriginal.bind(oContext));
return fWrapper.apply(oWrapperContext || oContext, a);
};
oContext[sMethodName].unwrapped = fOriginal;
};
/*
Reverts method sMethodName of oContext to reference original function,
the way it was before wrap() call
*/
function unwrap(sMethodName, oContext) {
if (typeof oContext[sMethodName] == 'function') {
oContext[sMethodName] = oContext[sMethodName].unwrapped;
}
};
This is the example I would use
<script type="text/javascript">
var before = function(){alert("before")};
var after = function(param){alert(param)};
var wrap = function(func, wrap_before, wrap_after){
wrap_before.call();
func.call();
wrap_after.call();
};
wrap(function(){alert("in the middle");},before,function(){after("after")});
</script>
You could do something like:
var wrap = function(func, pre, post)
{
return function()
{
var callee = arguments.callee;
var args = arguments;
pre();
func.apply(callee, args);
post();
};
};
This would allow you to do:
var someFunc = function(arg1, arg2)
{
console.log(arg1);
console.log(arg2);
};
someFunc = wrap(
someFunc,
function() { console.log("pre"); },
function() { console.log("post"); });
someFunc("Hello", 27);
Which gives me an output in Firebug of:
pre
Hello
27
post
The important part when wrapping this way, is passing your arguments from the new function back to the original function.
Maybe I'm wrong, but I think you can directly create an anonym function and assign it to myFunc:
myFunc = function(){
BeforeFunction();
myFunc();
AfterFunction();
}
In this way you can control the arguments of every function.

Categories