It seems to me that i misunderstand the behavior of the do ... while loop in JS.
Let's say we have a code like:
var a = [1,2,3,4,5];
var b = [];
var c;
do {c = a[Math.floor(Math.random()*a.length)];
b.push(c);}
while(c===4);
console.log(b);
Which is intended to roll out random item from array a if that item is not 4.
But if we roll several times we'll see that it doesn't actually prevent 4 from getting to array b. Why? I thought that it would work like this:
Roll random item from array a, store it to c and push c to b;
Check if (c===4) is true;
If it is — go to paragraph 1;
If it's not — log b to console.
Where am I mistaking and why does this code work in such a way? What are others way to 'ban' some item from array from being rolled randomly (except filtering the array) if this approach can't help me?
Do while runs and THEN checks. So it will get a random number from A, store that in C and push that to B, and THEN if C is 4, it will do another loop.
So if C is 4, it will still push it to B, it just won't continue after that.
You could do it like this:
var a = [1,2,3,4,5];
var b = [];
var c = a[Math.floor(Math.random()*a.length)];
while (c !== 4) {
b.push(c);
c = a[Math.floor(Math.random()*a.length)];
}
console.log(b);
I think this is what you're trying to do? Continuously push a random item from A into B unless you get the result 4, in which case, quit and go to console.log?
As explained by the commenters, you're still pushing 4. You can avoid it by make it very explicit what happens when.
var a = [1,2,3,4,5];
var b = [];
var c;
var keep_going = true;
while (keep_going) {
c = a[Math.floor(Math.random()*a.length)];
if (c === 4) {
keep_going = false;
} else {
b.push(c);
}
}
console.log(b);
So the way your code is written, you are not "bannning" 4 from being added to b. The code you have written will add a value from a to b and, if the value added equals 4, continue to add values from a to b until the last value added does not equal 4. So you will get results like:
b == [1];
b == [5];
b == [4,1];
b == [4,4,4,4,4,4,3];
Since do-while is a looping mechanism, I'm assuming you want to keep trying to add a value from a to b until you find one that is not 4. That would be
var a = [1,2,3,4,5],
b = [],
c;
do {
c = a[Math.floor(Math.random()*a.length)];
if(c!==4) { b.push(c); }
} while(c===4);
console.log(b);
This will produce the following values for b
b == [1];
b == [2];
b == [3];
b == [5];
Related
I actually want to pick an item from the array (A or B or C) and display it in a block. Then changes at 2 second interval and keep on cycling through.
<script type="text/javascript">
var arr = ["A","B","C"];
setInterval(function ChangeText() {
var span = document.getElementById("spnChanger")
var i = Math.floor(Math.random() * 3)
span.innerHTML = arr[i]
}, 2000);
</script>
Such as if A is randomly picked, A will be shown at first, followed by B and C and then back to A and loop endlessly
Such as if B is randomly picked, B will be shown at first, followed by C and A and then back to B and loop endlessly
Such as if C is randomly picked, C will be shown at first, followed by A and B and then back to C and loop endlessly
But all i can get is a random item from the array every time which cannot continuously go through the cycle.
Can anyone help? Thanks
You can definitely condense this a bit, but I left separate lines so you can more easily see what's going on;
var arr = ["A", "B", "C"];
var idx = Math.floor(Math.random() * 3); //initialize the index
var span = document.getElementById("spnChanger"); //this isn't changing, so you can look it up outside of the timer
setInterval(() => {
span.innerHTML = arr[idx];
idx++;
idx %= 3; //this is the mod based on the length of arr, this handles wrapping to the start
}, 2000);
I'm gonna use randojs.com to answer your question, so if you'd like to use my code, copy and paste this into the head tag in your HTML document:
<script src="https://randojs.com/1.0.0.js"></script>
And then you can use this nice short code:
var arr = ["A", "B", "C"];
var index = rando(arr).index;
setInterval(function(){
if(arr.length > 0){
document.getElementById("spnChanger").innerHTML = arr[index++ % arr.length];
}
}, 2000);
It doesn't matter how many items are in your array. This code will account for it automatically.
I don't know why I have a comma when I use join method. Can anyone explain?
function maskify(cc) {
var a = cc.slice(cc.length - 4, cc.length);
var b = cc.slice(0, cc.length - 4);
b = b.split("");
for (var i = 0; i < b.length; i++) {
b[i] = "#";
}
b.join("#");
console.log(b + a);
}
maskify("sadasdasdasdasdasd");
// result : #,#,#,#,#,dasd
Join() is the method of array which allows to join its element as string and returns. Join() takes one argument which is separator, the default value is ",". You need to specify empty string if you want to join without any separator. For reference refer MDN.
For your code, you are joining but not storing, and again converting it to string by using + operator with variable a
function maskify(cc) {
var a = cc.slice(cc.length - 4, cc.length);
var b = cc.slice(0, cc.length - 4);
b = b.split("");
for (var i = 0; i < b.length; i++) {
b[i] = "#";
}
var output=b.join("#");
console.log(output + a);
}
maskify("sadasdasdasdasdasd");
// result : #,#,#,#,#,dasd
When you use split on b, b is an array of individual characters. When logging b + a, since b is an array and a a string, + will act as string concatenation operator. b is converted to string using toString() implicitly. toString on array returns string of array elements joined by ,. So, you're getting comma in the final output.
Simple solution to solve this problem is to explicitly join the array elements before concatenating.
function maskify(cc) {
var a = cc.slice(cc.length - 4, cc.length);
var b = cc.slice(0, cc.length - 4);
b = b.split("");
for (var i = 0; i < b.length; i++) {
b[i] = "#";
}
b.join("#");
console.log(b.join('') + a);
}
maskify("sadasdasdasdasdasd");
Another way to achieve same results is using repeat
var str = 'sadasdasdasdasdasd';
var maskedStr = '#'.repeat(str.length -4) + str.slice(-4);
console.log(maskedStr);
Note that this is supported in latest browsers/environments only. Check the browser compatibility, if not supported use polyfill.
It's because when concatinating an array and a string, the array is implicitly converted into a string.
var array = [...];
array + "";
is the same as:
array.toString() + "";
and [4, 5].toString() is "4,5" (add a , by default).
Why?
Because, when this line is reached:
console.log(b + a);
a will be a string because it was cut from the string cc. And b is an array because it is the result of the split, and b.join don't change b to a string, it just return a string that you don't use and leaves b intact (so b remains an array).
Fix:
Use the result of b.join not b:
console.log(b.join("#") + a);
or:
b = b.join("#");
console.log(b + a);
i add
var c = b.concat(a);
c.join("");
It's working . Thanks u so much :D
var setOfCats = {}; //an object
while (r = true) //testing to see if r is true
{
var i = 0;
setOfCats.i = prompt ("What's your cat's name?", ""); //index object elements
alert ("Congratulations! Your cat has been added to the directory.");
var r = confirm ("Would you like to add another cat?"); //if r is true, then the loop should continue. if false, the loop should end.
i++
}
However, the loop does not end. I've been pondering this problem, with futile attempts, for the last 30 minutes. Any ideas?
Your comment is incorrect.
r = true doesn't test whether r is true; it assigns r to become true.
You need to compare the variable using the === operator.
Or you can just write while(r), since r itself is already true.
while (r = true)
You're setting r to true each loop iteration. You want while (r == true), or just while (r).
For clarity, r and setOfCats should be set outside the while declaration:
var setOfCats = [];
var r = true;
while (r) {
setOfCats.push( prompt ("What's your cat's name?", "") );
alert ("Congratulations! Your cat has been added to the directory.");
r = confirm ("Would you like to add another cat?");
}
You are re-assigning the value of r to true upon each iteration of the while expression. Therefore, it will always override the value.
You should do the while test with:
while(r === true)
or more idiomatic:
while(r)
This should work:
var setOfCats = {}; //an object
var r = true;
while(r) //testing to see if r is true
{
var i = 0;
setOfCats.i = prompt ("What's your cat's name?", ""); //index object elements
alert ("Congratulations! Your cat has been added to the directory.");
r = confirm ("Would you like to add another cat?"); //if r is true, then the loop should continue. if false, the loop should end.
i++
}
I am working with Col A, B & C. Col A contains A-E, Col B Contains 1, a, 3, b, 5 and Col C will be where I will store duplicated information (a and b would go into C1 & C2). Any help would be appreciated. In summary; compare A and B for similarity, output result into C
function appendString() {
var range = SpreadsheetApp.getActiveSheet().getRange("A1:A5");
var range2 = SpreadsheetApp.getActiveSheet().getRange("B1:B5");
var range3 = SpreadsheetApp.getActiveSheet().getRange("C1:C5")
var numRows = range.getNumRows();
var x = 0
// var numCols = range.getNumColumns();
j = 1 // row A
k = 2 // row B
m = 3 // row C
n = 1
// First loop though B
for (var i = 1; i <= numRows; i++) {
// set the current value...
var currentValue = range.getCell(i, j).getValue();
// In the log tell us the current value
Logger.log("Set A:" + currentValue);
// Loops though col B to compare to col A
for (var l = 1; l <= numRows; l++) {
// Sets the current value to compare value
var compareValue = range2.getCell(l, j).getValue();
Logger.log("Set B:" + compareValue)
// If the compareValue and the currentValue (match)
if (compareValue === currentValue) {
Logger.log("MATCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
// We will write the result to col C down one row
for (n; n <= x; n++) {
// this makes it only run once'
range3.setValue(currentValue);
Logger.log("Appending.................");
x = n + 3
}
}
}
}
}
I think your problem statement boils down to this: Fill column C with a list of unique values that appear in both column A and B.
There is a built-in javascript Array method Array.indexOf() that makes it very easy to search for matching elements. As the problem is defined, we want to search in a column, so to use that method we need a column to be represented as an Array. The Range.getValues() method allows us to load a whole range of values at once, and delivers them as a two-dimensional array, with rows as the first dimension. We need columns there, and we can achieve that by a matrix transposition.
So here's what we end up with. There isn't a built-in transpose(), so I've included one. As we search for matches, results are stored in an Array C, using the built-in Array.push() method. Finally, array C is treated as a two-dimensional array, transposed, and written out to the sheet in column C.
function recordMatches() {
var range = SpreadsheetApp.getActiveSheet().getRange("A1:B5");
var data = range.getValues();
// For convenience, we'll transpose the data, so
// we can treat columns as javascript arrays.
var transposed = transpose(data);
var A = transposed[0],
B = transposed[1],
C = [];
// Go through A, looking for matches in B - if found, add match to C
for (var i=0; i < A.length; i++) {
if (B.indexOf(A[i]) !== -1) C.push(A[i]);
}
// If any matches were found, write the resulting array to column C
if (C.length > 0) {
var rangeC = SpreadsheetApp.getActiveSheet().getRange(1,3,C.length);
rangeC.setValues(transpose([C]));
}
}
function transpose(a) {
return Object.keys(a[0]).map(function (c) { return a.map(function (r) { return r[c]; }); });
}
Reading documentation online, I'm getting confused how to properly define multiple JavaScript variables on a single line.
If I want to condense the following code, what's the proper JavaScript "strict" way to define multiple javascript variables on a single line?
var a = 0;
var b = 0;
Is it:
var a = b = 0;
or
var a = var b = 0;
etc...
Using Javascript's es6 or node, you can do the following:
var [a,b,c,d] = [0,1,2,3]
And if you want to easily print multiple variables in a single line, just do this:
console.log(a, b, c, d)
0 1 2 3
This is similar to #alex gray 's answer here, but this example is in Javascript instead of CoffeeScript.
Note that this uses Javascript's array destructuring assignment
You want to rely on commas because if you rely on the multiple assignment construct, you'll shoot yourself in the foot at one point or another.
An example would be:
>>> var a = b = c = [];
>>> c.push(1)
[1]
>>> a
[1]
They all refer to the same object in memory, they are not "unique" since anytime you make a reference to an object ( array, object literal, function ) it's passed by reference and not value. So if you change just one of those variables, and wanted them to act individually you will not get what you want because they are not individual objects.
There is also a downside in multiple assignment, in that the secondary variables become globals, and you don't want to leak into the global namespace.
(function() { var a = global = 5 })();
alert(window.global) // 5
It's best to just use commas and preferably with lots of whitespace so it's readable:
var a = 5
, b = 2
, c = 3
, d = {}
, e = [];
There is no way to do it in one line with assignment as value.
var a = b = 0;
makes b global. A correct way (without leaking variables) is the slightly longer:
var a = 0, b = a;
which is useful in the case:
var a = <someLargeExpressionHere>, b = a, c = a, d = a;
Why not doing it in two lines?
var a, b, c, d; // All in the same scope
a = b = c = d = 1; // Set value to all.
The reason why, is to preserve the local scope on variable declarations, as this:
var a = b = c = d = 1;
will lead to the implicit declarations of b, c and d on the window scope.
Here is the new ES6 method of declaration multiple variables in one line:
const person = { name: 'Prince', age: 22, id: 1 };
let {name, age, id} = person;
console.log(name);
console.log(age);
console.log(id);
* Your variable name and object index need be same
Specifically to what the OP has asked, if you want to initialize N variables with the same value (e.g. 0), you can use array destructuring and Array.fill to assign to the variables an array of N 0s:
let [a, b, c, d] = Array(4).fill(0);
console.log(a, b, c, d);
note you can only do this with Numbers and Strings
you could do...
var a, b, c; a = b = c = 0; //but why?
c++;
// c = 1, b = 0, a = 0;
do this if they have same value
let x = y = z = 0
otherwise
let [x, y, z] = [10, 30, 50]
console.log(x, y, z) // 10 30 50
The compressed type of that is here:
var a, b = a = "Hi";
& for 3 variables:
var x, y, z = x = y = "Hello";
Hope to be helpful!
This is completely correct:
var str1 = str2 = str3 = "value";
And if change one of their value, the value of other variables won't change:
var str1 = str2 = str3 = "value";
/* Changing value of str2 */
str2 = "Hi Web!";
document.write("str1 = " + str1 + " - str2 = " + str2 + " - str3 = " + str3);