I'm blocked with simple issue, infinite loop - javascript

it is my first question contribution here so i hope it will be ok with all the rules.
It is a simple question, i have basic knowledge of language, i have to change values every array[2n] when someone is enterying a value it will multiply the value they entered by the values in the array.
so : tableau[1,2,3,4,5,..,100] must become : if user enter 4 tableau[4,2,12,4,20..]
it is :
tableau = new Array(100);
var userInput = prompt('give me a value');
for (i = 0; i < tableau.lengt; i++) {
tableau[i] = i + 1;
if (i = 0) {
tableau[i] = i * userInput;
console.log('voici mon tableau : [' + i + '] : ' + tableau[i]);
var pair = i % 2;
if (pair = 0) {
tableau[i + 1] = tableau[i] * userInput;
console.log('voici mon tableau : [' + i + '] : ' + tableau[i]);
} else {
console.log('voici mon tableau : [' + i + '] : ' + tableau[i]);
}
}
}
I had issue to implement my code, if you can give me some tips to be able to have a full block of it, i read the help but wasn't able to fix it :(.
So here is my issue, with this code i have an infinite loop, and i am not able to see what is happening because my browser crash.
I hope it is not a dumb question and as loop are different for everyone i couldn't find my solution.
thank you in advance

There is different trouble on your code.
I made some correction, see live example below
tableau = new Array(100);
var userInput = prompt('give me a value');
for (var i = 0; i < tableau.length; ++i) {
var pair = i % 2;
if (pair == 0) {
tableau[i] = (i + 1) * userInput;
} else {
tableau[i] = i + 1;
}
}
console.log(tableau)

You're using assignment operator '=' for comparison here. It should be
if (i == 0)
instead.
Otherwise, what you're doing is to set i to 0 every time, so the loop never ends, beause i only have the values 1 (at the end of the loop) and 0 again.
Same for
if (pair == 0) {
as well, of course.
Btw., a good practice to overcome this issue is to write
0 == i
instead. This way, if you forget the '=' there won't be any assignment to i happening (you will get an error message).

= is used for assignment and == || === are used for comparison. In your if statement either use == or === . = will not work as it will always return true and hence the infinite loop.
This will be-
if (i = 0) {
//tableau[i] = i * userInput;
//console.log('voici mon tableau : [' + i + '] : ' + tableau[i]);
//var pair = i % 2;
if (pair = 0) {
this
if (i == 0) {
//tableau[i] = i * userInput;
//console.log('voici mon tableau : [' + i + '] : ' + tableau[i]);
//var pair = i % 2;
if (pair == 0) {

Related

How to know when a for loop is done without knowing how many iterations there will be?

using a for-loop in javascript i´m getting a not known amount of id´s, they´re not in an array but coming one by one.
is there a way to get an alert when there are no more id´s to retrieve meaning the for loop is done?
i can´t wrap my head around this, any help would be greatly appreciated.
thanks!
edited with code for clarification.
function iterateDevices(api) {
var count = api.getcount("devices"); var apiPath = dequotePath(api);
for (var i = 0; i < count; i++) {
var deviceApi = new LiveAPI(apiPath + " devices " + i); if (deviceApi) {
var deviceName = deviceApi.get("name"); var deviceid = deviceApi.id; //var
deviceName = deviceApi.get("parameters"); var className =
deviceApi.get("class_name"); var deviceApiPath = dequotePath(deviceApi);
var chainsCount; var chainApi; var j;
if ((className == "DrumGroupDevice") || (className ==
"AudioEffectGroupDevice") || (className == "InstrumentGroupDevice")){
//post(deviceName + " id " + deviceid + "\'\n"); //outlet(0,deviceid);
// arr.push(deviceName);
if (deviceApi.get("can_have_chains") == 1) { chainsCount =
deviceApi.getcount("chains"); // only racks have chains for (j = 0; j
< chainsCount; j++) { // post("id" + deviceid + " found device " +
deviceName + " at path \'" + deviceApiPath + "\'\n");
//outlet(0,deviceid); chainApi = new LiveAPI(deviceApiPath + " chains
" + j); iterateDevices(chainApi);
myFunction(); } chainsCount = deviceApi.getcount("return_chains");
// only racks have chains for (j = 0; j < chainsCount; j++) {
//post("2 found device " + deviceName + "id"+deviceid + " at path
\'" + deviceApiPath + "\'\n"); // outlet(0,deviceid); chainApi = new
LiveAPI(deviceApiPath + " return_chains " + j);
iterateDevices(chainApi);
}
}
}
}
}
} iterateDevices.local = 1;
The purpose of a for loop is to deal with a known number of iterations. If you want to deal with an unknown number of iterations, you would use a while loop.
Of course, this is programming, so lets look at the crazy things we can do:
Iterate over a collection. We dont necessarily know how many things
are in the collection, but we may want to iterate over all of them.
The number of things in the collection might even change as we're
iterating.
We can change how we iterate through the loop. That whole i++ part?
What if we replace it with i += 2? Or what if it's i -=1? Or i += j
and j changes while we're iterating?
We can change how we break out of the loop. You can put a break
statement in there to break out of the loop anytime. You can also
change the conditional of the loop. What if i < 100 is replaced by
i<j? Or what if we replace it with i<100 || q == true?
You may use a while loop instead of a for and insert a condition to terminate the loop.
Using pseudo-code, you could do something like:
other_ids = True // boolean var
while(other_ids) {
// do what you have to do
other_ids = FuncionToCheckWhetherThereAreNewIds
}
FuncionToCheckWhetherThereAreNewIds should be a function that gives you true if there are new ids and false if there are not.

Logical error in my function prevents count++ from working

I am struggling to find the last logical error in this code it still returns Found 0 wishes, rather than 12.
var msg = 'I wish to wish the WISH you wish to wish but if you wish '
+ 'the WISH the witches wish I won\'t wish the WISH you wish '
+ 'to wish';
document.writeln('Found ' + countTerms(msg) + ' wishes.');
function countTerms(phrase) {
var i = 1;
var count = 0 ;
var terms = phrase.split(' ');
for (i = 0; i < terms.length - 1; i++){
if (terms[i].toUpperCase() == 'WISH'){
return count++;
}
}
}
With return inside the for loop, for the very first match, we are returning count and then incrementing, which means function will return 0 there itself. And if there was no such match it will return undefined (default return).
You will need to return count after the for loop. Also, the condition in for loop has to be i < terms.length otherwise, we will miss the last value in the array.
var msg = 'I wish to wish the WISH you wish to wish but if you wish '
+ 'the WISH the witches wish I won\'t wish the WISH you wish '
+ 'to wish';
document.writeln('Found ' + countTerms(msg) + ' wishes.');
function countTerms(phrase) {
var i = 1;
var count = 0 ;
var terms = phrase.split(' ');
for (i = 0; i < terms.length; i++) {
if (terms[i].toUpperCase() == 'WISH'){
count++;
}
}
return count;
}
Please note, you can also simplify your code using Array.reduce. After splitting string into array, filter in only those values of array which have the value 'wish' and then return the length of the filtered array.
var msg = 'I wish to wish the WISH you wish to wish but if you wish '
+ 'the WISH the witches wish I won\'t wish the WISH you wish '
+ 'to wish';
document.writeln('Found ' + countTerms(msg) + ' wishes.');
function countTerms(phrase) {
return phrase.split(' ').filter(p => p.toUpperCase() === 'WISH').length;
}
You always return the first count directly, which is 0 at that point. To keep counting, just do count++ in the loop, and return count; after the loop is done.
Don't return inside loop
for (i = 0; i < terms.length - 1; i++){
if (terms[i].toUpperCase() == 'WISH'){
count++;
}
}
// Return hear
return count;
It's because you're returning a pre
-incremental value. This means that the variable is not updated until the return statement has finished running. to fix your code, change
return count++
to this
count++
and then return count at the bottom of the function, after the for loop.
There are two mistakes. Return the count after the loop.
Another one is in the for loop: you either use i < terms.length or i <= terms.length -1; or else you will miss the last 'wish'
var msg = 'I wish to wish the WISH you wish to wish but if you wish ' +
'the WISH the witches wish I won\'t wish the WISH you wish ' +
'to wish';
console.log('Found ' + countTerms(msg) + ' wishes.');
function countTerms(phrase) {
var count = 0;
var terms = phrase.split(' ');
for (let i = 0; i < terms.length; i++) {
if (terms[i].toUpperCase() === 'WISH') {
count++;
}
}
return count;
}

Copy string and increment version

For example if we have string str and I copy it it will be str_1, str_2, str_3 and so on..
If I copy str_2 then it will be str_2_1, str_2_2 and so on.
I have following logic but it does not work..
It should return 'Test2_5' (because Test2 AND Test2_4 already exists) but it returns 'Test2_4'
function createName(nameToCopy) {
var i;
var version = 1;
var nameCopiesArr = ["Test2", "Test2_2",
"Test2_3",
"Test2_4",
"Test2_2_2",
"Test2_3_1",
"Test2_2_1_2",
"Test2_2_3"
];
if (nameCopiesArr && nameCopiesArr.length > 1) {
for (i = 0; i < nameCopiesArr.length; i++) {
var indexes = nameCopiesArr[i].lastIndexOf('_') ? nameCopiesArr[i].match(/\d+$/) : 0
if (indexes) {
version = indexes[indexes.length - 1];
version = parseInt(version) + 1;
}
}
}
p = nameToCopy + '_' + version;
document.getElementById("demo").innerHTML = p;
return p;
}
<button onclick="createName('Test2')">Click me</button>
<p id="demo"></p>
You could search for all string which starts with the given name and a dash and an ending number. Then take the max number of ending and return the given string with an incremented version.
function createName(nameToCopy) {
var copies = ["Test2", "Test2_2", "Test2_3", "Test2_4", "Test2_2_2", "Test2_3_1", "Test2_2_1_2", "Test2_2_3"],
filtered = copies.filter(/./.test.bind(new RegExp(nameToCopy + '_' + '\\d+$'))),
version = filtered.reduce((v, s) => Math.max(v, +s.match(/\d+$/)[0]), 0);
return nameToCopy + '_' + ++version;
}
console.log(['Test2', 'Test', 'Test2_2'].map(createName));
More traditional
function createName(nameToCopy) {
var copies = ["Test2", "Test2_2", "Test2_3", "Test2_4", "Test2_2_2", "Test2_3_1", "Test2_2_1_2", "Test2_2_3"],
regexp = new RegExp(nameToCopy + '_' + '\\d+$'),
version = 0,
i, v;
for (i = 0; i < copies.length; i++) {
if (regexp.test(copies[i])) {
v = +copies[i].match(/\d+$/)[0];
if (v > version) {
version = v;
}
}
}
return nameToCopy + '_' + (version + 1);
}
console.log(['Test2', 'Test', 'Test2_2'].map(createName));
I update your code to test the number of the '_' char and if the current string contains the given input.
function createName(nameToCopy) {
var i;
var version = 1;
var nameToCopy_Nb = (nameToCopy.match(/_/g) || []).length; //number of the '_' char
var nameCopiesArr = ["Test2", "Test2_2",
"Test2_3",
"Test2_4",
"Test2_2_2",
"Test2_3_1",
"Test2_2_1_2",
"Test2_2_3"
];
if (nameCopiesArr && nameCopiesArr.length > 1) {
for (i = 0; i < nameCopiesArr.length; i++) {
var item_Nb = (nameCopiesArr[i].match(/_/g) || []).length;//number of the '_' char
if (nameCopiesArr[i].indexOf(nameToCopy) !== -1 && item_Nb === nameToCopy_Nb + 1) {
var indexes = nameCopiesArr[i].lastIndexOf('_') ? nameCopiesArr[i].match(/\d+$/) : 0
if (indexes) {
version = indexes[indexes.length - 1];
version = parseInt(version) + 1;
}
}
}
}
p = nameToCopy + '_' + version;
document.getElementById("demo").innerHTML = p;
return p;
}
But the answer of #Nina is good and probably the shortest !!! (I upvote her answer)
JSFiddle
I'm not sure what you're trying to do here, or why, so I can't really comment on your code. Just note that it is not too efficient, and not too understandable. And as a side note, your html doesn't call the code you wrote.
to answer your question of why it returns 'Test2_4' : your code loops through the hard coded values you put into the nameCopiesArr, and the version variable keeps the number of the current name + 1. And then you overwrite this with the result from the next entry in the array. Since the last entry in the array is 'Test2_2_3', you grab the last number there - which is 3 - and add 1 to that, so after your last iteration the version variable holds the value of 4 - and this is what you return.

Javascript: Reversing the loop ouput

Basically i'm creating a script to display the place value for set of numbers. Here's my script:
var arrn = '3252';
var temp = 0;
var q = arrn.length;
var j = 0;
for (var i = q-1; i >= 0; i--,j++) {
if (j!=0) temp = temp + ' + ';
{
temp += arrn[i] * Math.pow(10, j);
}
}
alert(temp);
My goal is to achieve 3000 + 200 + 50 + 2. But i get 2 + 50 + 200 + 3000. I tried temp.reverse() & sort functions but doesn't seem to work. Please help
Change
if(j!=0)temp=temp +' + ';
{
temp +=arrn[i]*Math.pow(10,j);
}
to
if(j!=0) {
temp=' + ' + temp;
}
temp = arrn[i]*Math.pow(10,j) + temp;
Live Example
Side note: Your braces in the first code block above are very misleading. What you have:
if(j!=0)temp=temp +' + ';
{
temp +=arrn[i]*Math.pow(10,j);
}
is
if(j!=0)temp=temp +' + ';
temp +=arrn[i]*Math.pow(10,j);
which is to say
if(j!=0) {
temp=temp +' + ';
}
temp +=arrn[i]*Math.pow(10,j);
the block in your version is not associated with the if, it's just a freestanding block.
Side note #2: Since you're using temp as a string everywhere else, I would initialize it with '' rather than with 0. Example The reason your string didn't end up with an extraneous 0 was really quite obscure. :-)
Just add the number to the beginning of the string instead of at the end:
for (var i = q - 1; i >= 0; i--, j++) {
if (j != 0) {
temp = ' + ' + temp;
}
temp = arrn[i] * Math.pow(10, j) + temp;
}
Demo: http://jsfiddle.net/Guffa/rh9oso3f/
Side note: You are using some confusing brackets in your code after the if statement. As there is a statement following the if statement, the brackets starting on the next line becomes just a code block, but it's easy to think that it's supposed to be the code that is executed when the condition in the if statement is true.
Another side note: the language attribute for the script tag was deprecated many years ago. Use type="text/javascript" if you want to specify the language.
How about temp.split("+").reverse().join(" + ")?
You can do this way. I know it can be optimised. But it works
var arrn='3252';
var temp=0;
var q=arrn.length;
var res = [];
var j=0;
for(var i=q-1;i>=0;i--,j++)
{
temp += parseFloat(arrn[i])*Math.pow(10,j);
res.push(arrn[i]*Math.pow(10,j));
}
res.reverse();
alert(res.join('+') + " = " + temp);
http://jsfiddle.net/he7p8y5m/
var arrn='3252';
var temp=new Array();
var q=arrn.length;
for(var i=0;i<=q-1; i++){
temp.push(arrn[i]*Math.pow(10,(q-i-1)));
}
temp = temp.join('+');
alert(temp);

Can't find issue in simple js for-loop

I am trying out javascript for (more-or-less) the first time and find myself completely baffled by the following .js script.
var pair = newArray();
var id = newArray();
var pairs = 2;
function newGame(){
var randomid = 0;
alert("newGame() called!");
// Sets a specific part of the image sprite to each pair[].
for (var i=0 ;i < pairs; i++){
alert("For loop started!");
pair[i] = "url(Cardfront.jpg) -"+100 * Math.floor((Math.random()*13)+0)+"px -"+200 * Math.floor((Math.random()*4)+0)+"px";
// For every pair, assigns a part of the image sprite to two id[]-s.
alert("Pair " + i + "is " + pair[i]);
for(var j=0; j < 2; j++) {
//the range of possible id-s the total number of cards - double the amount of pairs.
randomid = Math.floor((Math.random()*pairs*2)+0);
if (id[randomid] === null){
id[randomid] = pair[i];
alert("ID " + randomid + "is " + id[randomid]);
}
else j--;
}
}
alert("This is called after the for loop!");
}
When I call newGame() through a button, I receive the "newGame() called!" and then "This is called after the for loop!" alerts, then nothing.
I've spent a while googling and poking around trying to figure this out, but I'm at the end of my wits, it seems.
Change newArray() to new Array() I believe that is what is causing your error sir.
Good luck!
EDIT: To fix the other error I found you have the following:
if (id[randomid] === null) {
with 3 = sign. Change it to just two:
if (id[randomid] == null) {
and it should work the way you expect it to.
Unless you are really trying to use the strict comparisson operator, then there is something else bugging your code.
In this piece of code:
if (id[randomid] === null){
id[randomid] = pair[i];
alert("ID " + randomid + "is " + id[randomid]);
}
else j--;
You can't mix the if/else shorthand:
if(something)
//Do X
else
//Do y
With it's bracket notation:
if(something){
//Do X
} else {
//Do y
}
So, put brackets around your else:
if (id[randomid] === null){
id[randomid] = pair[i];
alert("ID " + randomid + "is " + id[randomid]);
} else {
j--;
}
The for loop should read:
for (var i=0; i<pairs.length; i++) {
...
}
pairs is being coerced into a numeric value (zero in this case), so the first comparison (i<pairs) will be the same as 0<0 which will never true.
:-(

Categories