I have a Javascript code that is not running in the console in Chrome. It is showing "Undefined" when I call the function.
let output = [];
let count = 1;
function fizzBuzz() {
while (count <= 100) {
if (count % 3 === 0 && count % 5 === 0) {
output.push("FizzBuzz");
} else if (count % 3 === 0) {
output.push("Fizz");
} else if (count % 5 === 0) {
output.push("Buzz");
} else {
output.push(count);
}
count++;
}
}
I am expecting it to output an array of numbers up to 100 but inserting "Fizz" for multiples of 3, "Buzz" for multiples of 5, and "FizzBuzz" for multiples of both 3 and 5.
You have the following code
let output =[];
let count = 1;
function fizzBuzz() {
while(count<=100) {
if(count % 3 === 0 && count % 5 === 0){
output.push("FizzBuzz");
}else if (count % 3 === 0){
output.push("Fizz");
}else if (count % 5 === 0){
output.push("Buzz");
}else{
output.push(count);
}
count++;
}
}
which you are executing by calling fizzBuzz(). You're getting undefined because when you call fizzBuzz() in the console you're seeing the return value of the execution, which in your code doesn't ever return anything, so we get undefined.
You have two options.
Return output at the end of your function, outside of the while loop. In this case, it'd be best to also move your output and count variables inside, like so
function fizzBuzz() {
let output =[];
let count = 1;
while(count<=100) {
if(count % 3 === 0 && count % 5 === 0){
output.push("FizzBuzz");
}else if (count % 3 === 0){
output.push("Fizz");
}else if (count % 5 === 0){
output.push("Buzz");
}else{
output.push(count);
}
count++;
}
return output;
}
We move the output and count declarations inside so that every time we call fizzBuzz() we start from scratch. If we kept them outside, then if you called fizzBuzz() twice, we'd see the results from the first call in the results from the second call as well.
Your second option is to call fizzBuzz() with how your code currently is, and then print the value of output. I think you're just making a simple mistake and don't realize that your fizzBuzz doesn't return anything.
fizzBuzz();
console.log(output);
or, if you're executing this in your browsers developer console then
fizzBuzz()
output
You are missing a return statement for the output
let output =[];
let count = 1;
function fizzBuzz() {
while(count<=100) {
if(count % 3 === 0 && count % 5 === 0){
output.push("FizzBuzz");
}else if (count % 3 === 0){
output.push("Fizz");
}else if (count % 5 === 0){
output.push("Buzz");
}else{
output.push(count);
}
count++;
}
return output;
}
console.log(fizzBuzz());
If you want run your code without getting undefined then you can use var instead of using 'let'. Due to the variable block scope you are getting undefined.
Just replace let with var.
Then return output variable in your function body. use console.log(your function name)
I tried to make 3 conditions in one array.forEach, but this give me incorrect output. Is it possible to short my code to one array.forEach? Have 3 conditions inside it?
var array = []; // create empty array
for (var i = 1; i < 101; i++) {
array.push(i); // write in array all values of i, each iteration
}
array.forEach((number) => {
if (array[number] % 3 === 0 && array[number] % 5 === 0) {
array[number] = "FizzBuzz";
}
});
array.forEach((number) => { //
if (array[number] % 3 === 0) {
array[number] = "Fizz";
}
});
array.forEach((number) => {
if (array[number] % 5 === 0) {
array[number] = "Buzz";
}
});
for (let i = 0; i < array.length; i++) { //output array elements
console.log(array[i]);
}
First pointer: that's a lot of whitespace.
Second pointer, rather than creating an array then cycling through that array, you can do it all in one loop, using the if....else block; something like this:
for (var i = 1; i < 101; i++) {
if (i % 3 === 0 && i % 5 === 0) {
console.log("FizzBuzz");
}
else if (i % 3 === 0) {
console.log("Fizz");
}
else if (i % 5 === 0) {
console.log("Buzz");
}
else {
console.log(i);
}
}
You are "walking over" the Array multiple times.
IMHO the most important Array Method to learn is Map:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Which "walks over" the Array and returns a new value for that Array index
let arr = Array(100)
.fill((x, div, label) => x % div ? "" : label) //store Function in every index
.map((func, idx) =>
func(++idx, 3, "Fizz") + func(idx, 5, "Buzz") || idx
);
document.body.append(arr.join(", "));
fill takes a single Object, it is not executed 100 times!
Since JavaScript Functions are Objects this code declares a function once
Note the ++idx because we want to start at 1, not 0
In JavaScript ""+"" is a Falsy value, thus it returns the idx value for non-FizzBuzz numbers
More Array Methods explained: https://array-methods.github.io
I want to exectute a function, preferably inside the forEach, for every element that is surrendered by 2 higher or equal number, or if its first or last element, just compared to second, or second last number.
I come up with this code, but I'm sure there is a better way:
var Pointdata = [98,59,39,0,48,85,19,43,3,98,65,100];
Pointdata.forEach(function(Current,i,array){
if (Current <= array[i+1] && Current <= array[i-1]) {
DrawPoint(Current,i,array);
}
else if (Current <= array[i+1] && i == 0) {
DrawPoint(Current,i,array);
}
else if(Current <= array[i-1] && i+1 == array.length) {
DrawPoint(Current,i,array);
}
function DrawPoint(Current,i,array) {
// marks peak points of canavas chart.
}
You could use just a single condition inside, Current is a.
if ((i + 1 === array.length || a <= array[i + 1]) && (i === 0 || a <= array[i - 1])) {
DrawPoint(a, i, array);
}
What about this?
for (i = 1; i < array.length - 1; i++) {
var Current = array[i];
if (Current <= array[i+1] && Current <= array[i-1]) {
DrawPoint(Current,i,array);
}
}
Couple of benefits:
You can skip edge cases like start and end indices
Only one conditional to think about
But if you want to keep those edge cases you can write them all in one if block separating them by or conditions like if ((Current <= array[i+1] && Current <= array[i-1]) || (Current <= array[i+1] && i == 0) || (Current <= array[i-1] && i+1 == array.length))
function markPeaks(data, draw) {
var xs = [Infinity].concat(data).concat(Infinity)
xs.forEach(function(x, i, array) {
if (Number.isFinite(x)) // skip first and last
if (array[i-1] >= x && x <= array[i+1]) // n-1 ≥ n ≤ n+1
draw(x, i-1, array) // minus1 because of 1st 'helper' Infinity
})
}
markPeaks(/*pointdata, /*drawpoint*/)
Hey so I am making a 2D tile game, or really I am just messing around. I have made the map from an array, where 0 represents nothing, and other characters represents a walkable tile.
var map=[["t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t"],
["l","1","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","r"],
["l","r","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","r"],
["l","1","t","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","l","r"],
["l","1","1","t","t","t","t","t","t","t","t","t","t","t","t","r","0","0","l","r"],
["l","b","b","b","b","b","b","b","b","1","1","b","b","b","b","b","t","t","b","r"],
["0","0","0","0","0","0","0","0","0","l","r","0","0","0","0","0","0","0","0","0"],
["0","0","0","0","0","0","0","0","0","l","r","0","0","0","0","0","0","0","0","0"],
["0","0","0","0","0","0","0","0","0","l","r","0","0","0","0","0","0","0","0","0"],
["0","0","0","0","0","0","0","0","l","1","1","r","0","0","0","0","0","0","0","0"],
["0","0","0","0","0","0","0","l","1","1","1","1","r","0","0","0","0","0","0","0"],
["t","t","t","t","t","t","t","1","1","1","1","1","1","t","t","t","t","t","t","t"]];
On screen it looks like this
You see my moveable character here as well.
Now I have come this far, and I'd like my character to collide with the empty tiles represented as the value of 0 in my map array.
This is my code for checking collision (brackets are correct in the script):
function collisioncheck(ind){
for(var i in map){
for(var j in map[i]){
if(yass==true){
if(map[i][j]==0){
if(ind==0 && playerPosX==j*32+32 && playerPosY>i*32-32 && playerPosY<i*32+32){
return false;
}else if(ind==1 && playerPosX==j*32-32 && playerPosY>i*32-32 && playerPosY<i*32+32){
return false;
}else if(ind==2 && playerPosY==i*32+32 && playerPosX>j*32-32 && playerPosX<j*32+32){
return false;
}else if(ind==3 && playerPosY==i*32-32 && playerPosX>j*32-32 && playerPosX<j*32+32){
return false;
}else{
return true;
}
}
}else{
return true;
}
}
}
var yass=false;
function exist(){
for(var i in map){
for( var j in map[i]){
if(map[i][j]==0){
yass=true;
break;
}
}
}
So, this works. But only for the first 0 in the map. My problem is that the return statements breaks the for-loop and function. So my character will not collide with any other blank tile but the first one.
I will have to rewrite this, but is there any smart solution to this?
Link to jsfiddle here (Character not visible)
You're on the right track, your loop only runs for one iteration because you always return something after an iteration. However, you should only call return when you know the final result, because - as you said - it will exit the function.
It is correct to call 'return false' right away after a collision is detected, because if the player collides with at least one block, then there is a collision. On the opposite, 'return true' should only be called when you are sure that there are no collisions at all on the entire board, and you need to test every block on the map before you can confirm this.
function collisioncheck(ind) {
for (var i in map) {
for (var j in map[i]) {
if (yass == true) {
if (map[i][j] == 0) {
if (ind == 0 && playerPosX == j * 32 + 32 && playerPosY > i * 32 - 32 && playerPosY < i * 32 + 32) {
return false;
} else if (ind == 1 && playerPosX == j * 32 - 32 && playerPosY > i * 32 - 32 && playerPosY < i * 32 + 32) {
return false;
} else if (ind == 2 && playerPosY == i * 32 + 32 && playerPosX > j * 32 - 32 && playerPosX < j * 32 + 32) {
return false;
} else if (ind == 3 && playerPosY == i * 32 - 32 && playerPosX > j * 32 - 32 && playerPosX < j * 32 + 32) {
return false;
}
// else: do nothing. (i.e. let the loop run for the next block)
}
} else {
return true;
}
}
}
return true;
}
What we do here is go through all the blocks, if we find a collision we return false and exit the function. We only reach the 'return true' statement if we went through all the blocks without finding any collision, which is exactly what you want.
You need to use continue instead of return in the last else of your main if/else block on line 15