javascript function won't loop - javascript

Here is a piece of a javascript practice problem that I am working on:
function combo(str){
var splitStr=str.split("");
for (var i=0; i<splitStr.length; i++){
return splitStr[i];
}
}
console.log(combo("dog"));
Why won't the loop return all three letters? It prints "d" and stops. If I take the loop out of the function, it works.
What am I doing wrong? Please explain.

return ends the invocation of the function, giving you back whatever is after that return
Your code structure looks like you wanted it to act like yield but ES5- does not support this so you can't use it (yet), and you would still have other problems (i.e. you'd be logging just the first generated result)
Instead, pass your console.log (bound to console) into a the loop;
function combo(str, callback){
var splitStr=str.split("");
for (var i=0; i<splitStr.length; i++){
callback(splitStr[i]);
}
}
combo('dog', console.log.bind(console));

With return you will end the function and come out of it with that data, next things wont be called
You can return an array instead like this.
function combo(str){
return splitStr=str.split("");
}
console.log(combo("dog"));

You are returning from inside the for loop and this ceases the function's execution. If you want to return each letter of the array, just return the split array itself:
function combo(str) {
return str.split("");
}
The behavior you seem to want is somehow achievable using generator function (function*).
function* combo(){
var splitStr = str.split("");
for (var i=0; i < splitStr.length; i++){
yield splitStr[i];
}
}
Then you'd invoke it like this:
var generator = combo("dog");
console.log(generator.next()) //d
console.log(generator.next()) //o
console.log(generator.next()) //g
Please note, however, that so far only few browser support this feature.

return stops the execution of the function. The rest of the loop is not happening.

'return' within the loop ends the loop and returns the first value, since it allowed the loop to run only once.
putting the 'return' statement outside of the scope {} of the loop will allow the loop to continue to run/repeat.

Related

for loop calculation syntax within a function is not correct

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

Javascript – creating "some" function

Trying to create "some" function. i.e., return true if any of the elements in teh array satisfies the condition
function some(array, predicate) {
for (var i = 0; i < array.length; i++) {
if (predicate(array[i]))
return true;
}
return false;
}
console.log(some([NaN, 3, 4], isNaN));
// → true
console.log(some([2, 3, 4], isNaN));
// → false
Question 1: Above is the solution in the book and I'm not sure why "return false" would overwrite "return true" in every case. The above solution seems to suggest that "return false" will be run only if "return true" was never run – WHY??
My solution looked like this.
var some = function(array, condition) {
var answer = false;
for(var i=0; i<array.length; i++) {
if(condition(array[i])) {answer = true};
}
return answer
};
Question 2: Is the book solution better because it takes less memory (ie the "answer" variable)?
Thanks!
return controls where the execution pointer is located for the currently executing script. When return is encountered it moves the execution pointer out of the function, and as a result, the function will stop executing. This means that if return true is executed, return false will not be.
The solution in the book is predicated on the fact that the return keyword used within the body of a for loop will cause the loop to stop execution and return.
Take a look at the at the Interrupt a function section of the return documentation, which states:
The return statement ends function execution and specifies a value to
be returned to the function caller.
In your example, as soon as the condition is matched, the book's solution will no longer continue to iterate through the array and will return (since that's what return does per the definition above).
Let's look at your solution:
var some = function(array, condition) {
var answer = false;
for(var i=0; i<array.length; i++) {
if(condition(array[i])) {answer = true};
}
return answer
};
What happens if the condition is met? You're setting the answer to true, but the loop will continue to check subsequent elements in the array.
Consider the use case where the array is very large and you want to find a specific value within the array.
Which do you think would be more efficient: the one that stops after it finds the match or the one that returns the match only after having looking at all elements?
In this case, the answer is the latter. Don't keep looping through all elements if you've already found what you need.
When the execution hits a return statement, it leaves the current function regardless of which block it was in within that function.
As soon as an array element corresponds to the predicate, it returns true. If the execution exits the for loop normally, it means not a single value was valid, so we can return false.
The book's answer is better, not because it doesn't create an extra variable (that doesn't matter), but because it doesn't check all variables every time. As soon as an array element is valid, it exits the function.
You can use the built in method of Array, some():
var test = [NaN, 3, 4].some(isNaN); // true
What that function does is
function some(array, predicate) { // return a boolean value (true, false)
// as soon an Array key matches `predicate`
for (var i = 0; i < array.length; i++) {
if (predicate(array[i])) return true; // if Array key isNaN exit function as `true`
}
// We're 1. already out of the function or 2. all keys are looped.
// This function needs to return a boolean so exit with `false`
// since all Array keys are Numbers
return false;
}
the above explains it all. Remember the part that says:
"return a boolean value (true, false) as soon an Array key matches predicate"
In your example, you're not exiting the function, so if you passed for example an
array of 1000 keys, every single key would be looped, which the function is not meant to do since it's purpose it to:
Return (exit) as true if at least one key matches the predicate condition
looping all other keys is useless since we already discovered that one key matches.
Yes, var consumes interpreter memory (nothing to worry about).

Does the ForEach loop allow using break and continue?

Does the ForEach loop allow us to use break and continue?
I've tried using both but I received an error:
Illegal break/continue statement
If it does allow, how do I use them?
No, it doesn't, because you pass a callback as a return, which is executed as an ordinary function.
Let me be clear:
var arr = [1,2,3];
arr.forEach(function(i) {
console.log(i);
});
// is like
var cb = function(i) {
console.log(i);
// would "break" here do anything?
// would "continue" here do anything?
// of course not.
}
for(var j = 0; j < arr.length; j++) {
cb(arr[j]);
}
All forEach does is call a real, actual function you give to it repeatedly, ignore how it exits, then calls it again on the next element.
In that callback function if you return it will incidentally work like continue in the case of forEach. Because the rest of the function won't execute that time, and it will be called again. There is no analogue of break.
Ruby supports this flexibility, using blocks/procs instead of methods/lambdas.
Per Mozilla's documentation:
Note : There is no way to stop or break a forEach loop. The solution is to use Array.every or Array.some. See example below.
every and some are exactly like forEach, except they pay attention to the return value of the callback. every will break on a falsey value and some will break on a truthy value, since they shortcircuit. They are exactly analogous to && and ||. && tests whether every expression is truthy, || tests for whether some is, which should help you remember how short-circuiting works with every and some. When in doubt, try it.
As already answered, you cannot use continue or break inside a JavaScript Array.prototype.forEach loop. However, there are other options:
Option 1
Use the jQuery .each() function (Reference).
Simply return true to continue, or return false to break the loop.
Option 2
Just use return to continue or throw new Error() to break. I don't necessarily recommend doing it this way, but it's interesting to know that this is possible.
try {
[1, 2, 3, 4].forEach(function(i) {
if (i === 2) {
return; // continue
}
if (i === 3) {
throw new Error(); // break
}
console.log(i);
});
}
catch (e) {
}
The expected result is just 1

Why can't I assign for loop to a variable?

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.

Is there a loop "start-over"?

There is continue; to stop the loop and move to the next loop
There is break; to stop the loop and move to the end of the loop
Isn't there some kind of start; that stop the loop and move to the beginning of the loop?
I know it is easy to achieve all of these three actions by just modifying the value of i, but I always try to look for already built-it functions.
Resetting the value of your loop variable to the initial value then calling continue is as close as you'll get.
For example:
for(var i=0; i<20; i++) {
if(somecondition) {
i=-1; continue;
}
}
No - there is no keyword or other way to do it automatically.
As you already mentioned you can just modify the loop condition variable(s) within your loop. Easy if it's a simple i counter, but of course you may have more initialisation to do than just a simple counter.
Or you can do something like the following:
restartLoop:
while (true) {
for (var i=0, j=100000, x="test"; i < 1000; i++, j--, x+= ".") {
if (/*some condition, want to restart the loop*/)
continue restartLoop;
}
break;
}
The continue restartLoop will jump back out to continue with the next iteration of the while loop, which then immediately starts the for loop from the beginning including all of the initialisation code. If the for exits normally the break statement after it will break out of the containing while loop.
I don't really recommend doing this in a general sense, but if your loop initialisation process was really complicated it could be worth it because then you wouldn't need to repeat it all inside the loop. If you needed to do even more initialisation than fits nicely in the for statement's initialisation expression you can easily put it just before the for loop inside the while and it will all be re-run...
If you want to avoid jumps or the equivalent of goto statements that many of us have been trained to avoid, you could use a local function for the loop and a test on the return value to see if you should just call it again:
function doItAll() {
// put state variables other than the actual loop control here
function doTheLoop() {
for(var i=0; i<20; i++) {
if (somecondition) {
return(true); // run the loop again
}
}
return(false); // done running the loop
}
while (doTheLoop()) {}
// do some things after the loop
}
No. (Just to rule out a "I just haven't heard of it, either" - it isn't mentioned at https://developer.mozilla.org/en/JavaScript/Reference/Statements.)
continue works by simply skipping the rest of the loop body. break works by skipping the rest of the loop body and then ending the loop. A start function would have to somehow "rewind" the state of the program - but not all of the state of the program, since presumably you don't want to lose what you did, either - to where it was when the loop began, which is not something that any programming language that I have seen provides.
You could have the loop in a function that calls itself recursively:
function loopIt(numTimes) {
if (numTimes < 3) {
for (x = 0; x < 20; x++) {
if (x == 5) {
loopIt(numTimes+1);
break;
}
}
}
}
You can obviously change the conditions to fit you logic as the above is a simple example.

Categories