I am trying to remove the let reassignment in the below function within a for block scope.
I want to accumulate the value within the block scope of for loop but not to access a closure or global variable(totalValue) which is outside of for loop block scope.
Because it makes the code more readable and maintainable for bigger functions.
I am looking for any alternate way which removes the let re-assignment pattern as shown below to acheive the same functionality.
function howToRemoveLetReassignmentForTheBelowScenario(target: number) {
let totalValue: number = 0;
for (
let i = 0;
i < target; // iteration is happening based on a condition where both variables are of number type. Wanted to highlight the point that there is no array.
i++
) {
const calculatedValueForEachIteration: number = i + Math.random()
totalValue += calculatedValueForEachIteration; // `let` re-assignmnet hapening here.
}
return totalValue
}
Playground link
Using Array(n) you can use reduce:
const target = 10;
const totalValue = [...Array(target).keys()]
.reduce((acc, value) =>
acc += (value + Math.random())
);
console.log(totalValue);
I don't think there is a way using "for" loop. How do we return the variable out of for loop if the variable scope is only within for loop? "for" is not a function that returns something.
I'm not quite sure what you mean by 'let reassignment pattern'. Your options are either a loop (for, while) or using array reduce as in other answers. My opinion is that the for loop is more readable than creating an array and using array reduce. I don't know if this is just because I am relatively new to JavaScript. You're still going to need to run the same code in a loop to calculate the subtotal (subTotal += newValue). I feel that, as a reader, it is quite apparent what is happening in your code - the function is written well, defining variables at the right scope, and performing a single, simple task). It just needs a name that describes the functionality to make it immediately apparent to the user.
Another possible consideration is that (from a few tests with a target of 1000), a for loop comes in at 0.02ms and creating an array and then performing an array reduce takes between 0.14ms and 0.7ms. While 0.7ms is still small, it seems like a sacrifice to gain little readability.
If you're really concerned about readability, I would recommend using a class with a self-explanatory name and clear method names. This makes the functionality really understandable when a reader looks at it:
class Accumulator {
#subtotal = 0;
add(n: number) {
this.#subtotal += n;
}
getTotal() {
return this.#subtotal;
}
}
function sumConsecutiveNumbers(from: number, to: number) {
let accumulator = new Accumulator();
for (let i=from; i <= to; i++) accumulator.add(i);
return accumulator.getTotal();
}
Related
what is the actual syntax for the for loop?
what I want to do is to calculate 2 number variables inside a function using a for a loop.
I am going over and over the internet and I cannot find anything that can help me specifically for this task I was given to do.
I am not looking for the answers, just for a guideline or a hint.
or just give me the syntax and I will try my best to adjust it to my needs.
just so you have a better understanding of the task, here it is.
Features
Instead of hardcoding Y (the result of the Fibonacci of X), calculate it with a for loop
The calculation should be wrapped in a function, that gets X as an argument, and returns Y
After the function, you should call the function, and assign the returned value in your HTML to present to the user
btw, i know that i did not put the innerHTML correcly, and also i did not do the syntax right, this is actually what i am asking here.
thank you!!
i have tried this:
var answer = document.getElementsByClassName("paragraph")
function calc (x){
for (let a = 2; a <= x; a++){
answer = document.textContent("this is a pr")
}
return calc
}
calc(2)
You should avoid to use classname, instead use .querySelectorAll
You don't need to specify how many answer exists if your calc() is just 2.
let answer = document.querySelectorAll(".paragraph");
function calc(x) {
for (let a = 0; a <= x; a++) {
answer[a].innerText = "this is a pr";
}
}
calc(2);
<p class="paragraph">A</p>
<p class="paragraph">B</p>
<p class="paragraph">C</p>
<p class="paragraph">D</p>
<p class="paragraph">E</p>
I don't know if this is what you're searching for but it's this is the standard for loop function to achieve these types of result.
function calc(x){
let sum = 0;
for (let a=0; a<x; a++){
sum+=a;
}
return sum;
}
console.log(calc(5));
The Syntax of the loop in your code is correct, the thing is that you cannot return your function inside itself without calling it as you have done in your code.
'return calc' is wrong. You should use 'return calc(argument-Variable or value)' as you have a parameter passed in your function, but this should only be used if you are writing a code of recursion. If not you should return a variable.
Refer to the code below for further clarifications
let example = {
a:20,
b:40,
c:60
}
for(let j=0,i in example){
console.log(example[i]*j);
j++;
}
Why normal for loop can have multiple variable declarations, but for-in loop cannot? Or am I doing this somehow wrong?
You're writing a code that's not syntactically correct.
in JavaScript you cannot use for-in expression with any other assignment expression.
You can simply pull out the j=0 assignment out of the for loop and that should fix the error
let example = {
a:20,
b:40,
c:60
}
let j=0
for(i in example){
console.log(example[i]*j);
j++;
}
[Edit] I have the found the following content in the official MDN site for the same scenario
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
As per the site - it's a publicly known issue that ChromeV8 and other browsers are trying to look into
For more info check the following references
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_for-in_initializer
https://bugzilla.mozilla.org/show_bug.cgi?id=748550
https://bugzilla.mozilla.org/show_bug.cgi?id=1164741
I can understand the frustration, you're using the same keyword so why doesn't it behave similar? But I think you should think about it this way:
for is a way to define a loop, for as long as some condition is true, with different way for how to define that condition.
In a regular for loop, you loop as long as the middle part (the condition) is true:
for(let i = 0; i < 10; i++)
This is similar to how a while loop might work, but it's a syntactic short cut:
let i = 0;
while (i < 10) {
i++;
}
So the for..in is a for loop that has another sort of condition, for every property in this object, so as long as you have more properties it will keep looping.
You could write that like this as well:
const keys = Object.keys(example);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const value = example[key];
}
You also have for...of, which loops over items in a array, but that is syntactic sugar for:
for(let i = 0; i < array.length; i++) { const item = array[i]; }
Also consider how a do...while loop is like a while loop but with some slightly different rules and behavior. Rather than getting frustrated with the syntax try to understand how it's saving you time by making your code a little less wordy, but in order to do that it needs to be a little different for each case. The alternative would be to have very many language keywords.
I tried changing your code to not declare any variables inside the parentheses of the for loop. I have never seen this done; maybe it's possible, but it would be simpler to declare a variable above the for loop, like this (assuming that's what you were hoping to do):
let example = {
a:20,
b:40,
c:60
}
let j=0
for(let i in example){
console.log(example[i]*j);
j++;
}
Edit: As mentioned in the comments: "You should probably add a let before the i declaration, otherwise it's going to be globally defined." I've just changed that in the snippet!
I’m doing an exercise on Code School, and I don’t understand how the loop works.
There is an i, but I don’t see it used. Normally you use it somewhere. Otherwise, what is the for loop for?
var puzzlers = [
function(a) { return 8 * a - 10; },
function(a) { return (a - 3) * (a - 3) * (a - 3); },
function(a) { return a * a + 4; },
function(a) { return a % 5; }
];
var start = 2;
var applyAndEmpty = function(input, queue) {
var length = queue.length;
for (var i = 0; i < length; i++) {
input = queue.shift()(input);
}
return input;
};
alert(applyAndEmpty(start, puzzlers));
It's used in the test to see if you have reached the end of the loop or not (the second part of the for statement).
Without the loop boundaries defined in the loop.
The loop will never end!
The variable is simply used to count the iterations of the loop. The loop ends after length iterations as kept track of by i.
In this case i serves no other purpose.
You don't have to use the i all the time, but its there if you need it. Normally if you dont use the i you use instead whats called a for-each loop instead. for-each is just a simpler way of writing a for loop without needing an explicit index variable.
Javascript doesn't have a simple for-each loop as part of the language, and I think they want to keep it as a for loop just to keep the lesson simple, but if you want to learn more about for-each in javascript, take a look at this question
It is being used - to ensure that the loop iterates length times.
If you are going to count from 0 to length - 1, you need something to keep track of the count, right?
Q1. I would like to confirm whether Version 1 of below code is more efficient than Version 2? I'd like to know for future reference so I will be writing codes according to the style of either V1 or V2.
Q2. How does one measure efficiency of the code? (Doesn't have to be in depth, I just want to have a rough idea)
Version 1:
function average(array) {
return array.reduce(function(a,b) { return a + b; }) / array.length;
}
Version 2:
function average(array) {
function plus(a,b) { return a + b; }
return array.reduce(plus) / array.length;
}
Edit: assuming that at a later stage I would be writing much more complex code and I would like to get into the habit of writing efficient code now. I know that for simple one-liners there's no explicit difference.
These functions are equally efficient from a big-O perspective. The reason they are the same, is that they both pass a function into reduce() (the way in which the function is declared is different, but it's the same underlying structure and thus the same efficiency). The functions are otherwise the same. If I were you, I'd opt for the second case as it is probably easier to maintain.
If you want, you can use a speed test, but honestly it's a waste of your time as these two approaches are identical.
With a sequential loop, it's far faster:
http://jsperf.com/anonymous-vs-named-function-passing/2
function average3(array) {
var sum =0;
for( var i=0, len=array.length; i< len; i++ )
sum+=array[i];
return sum/array.length;
}
You will have the same result. Or difference will be negligible. Depends on JS engine and how good its optimizer is.
As others suggested you can use jsperf.com for speed tests.
But if you really care about performance then check third case here
http://jsperf.com/anonymous-vs-named-function-passing/3
They are the same... but you could optimize by avoiding to create a new closure of the sum function.
function sum(a,b){
return a+b;
}
function average(array){
return array.reduce(sum) / array.length;
}
This way sum won't hold a reference to array in its context; and a new instance of sum with the context won't be necessary. Remember that a closure will hold a reference of the arguments of the function that contains it even if you don't use those arguments.
This means that a new function sum won't be instantiated every time that you call average.
So I am just wondering why the following code dosen't work. I am looking for a similar strategy to put the for loop in a variable.
var whatever = for (i=1;i<6;i++) {
console.log(i)
};
Thanks!
Because a for loop is a statement and in JavaScript statements don't have values. It's simply not something provided for in the syntax and semantics of the language.
In some languages, every statement is treated as an expression (Erlang for example). In others, that's not the case. JavaScript is in the latter category.
It's kind-of like asking why horses have long stringy tails and no wings.
edit — look into things like the Underscore library or the "modern" add-ons to the Array prototype for "map" and "reduce" and "forEach" functionality. Those allow iterative operations in an expression evaluation context (at a cost, of course).
I suppose what you look for is function:
var whatever = function(min, max) {
for (var i = min; i < max; ++i) {
console.log(i);
}
}
... and later ...
whatever(1, 6);
This approach allows you to encapsulate the loop (or any other code, even declaring another functions) within a variable.
Your issue is that for loops do not return values. You could construct an array with enough elements to hold all the iterations of your loop, then assign to it within the loop:
arry[j++] = i;
You can do this, but it seems that you might want to check out anonymous functions. With an anonymous function you could do this:
var whatever = function(){
for (var i=1;i<6;i++) {
console.log(i);
}
};
and then
whatever(); //runs console.log(i) i times.