My browser lags when I try a loop function? - javascript

I wrote a simple nested loop function to multiply all items in an array and output the total value, but each time is I run a loop function my browser either crashes or doesn't stop loading
function multiplyAll(arr){
Let product = 1;
for(let i = 0; i <
arr.length; i++){
for(let j = 0; j <
arr[i].length; j *= product);
}
return product;
}
multiplyAll([[1], [2], [3]]);

You are creating an infinite loop here because of
for (let j = 0; j < arr[i].length; j *= product);
Here, j is always 0.
If you want to multiply all the nested value then you should do as:
function multiplyAll(arr) {
let product = 1;
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; ++j)
product *= arr[i][j];
}
return product;
}
console.log(multiplyAll([[1], [2], [3]]));
If you just want to multiple all the nested value then you can simply do as:
function multiplyAll(arr) {
return arr.flat().reduce((acc, curr) => acc * curr, 1);
// If you want to get numbers at any depth then you can flat at any level
// using Infinity as
// return arr.flat(Infinity).reduce((acc, curr) => acc * curr, 1);
}
console.log(multiplyAll([[1], [2], [3]]));

Well, it looks like you have multiple issues, two of them are already as following:
In line 2 you wrote once Let with a big letter at the beginning.
Your second array needs an {} otherwise it will error out
Can you please explain to me j*= product? Can you maybe include a few examples of how you would call this Code and what kind of response you would get? depending on that I will create you a Clear answer!

Related

Quick sorting array in JavaScript

const arr = [5,3,2,6,1];
const quickSort = (arr) => {
for(let j = 0; j < arr.length; j++) {
let index = null;
let min = arr[0];
for(let i = 0; i < arr.length; i++) {
if(arr[i] < min) {
min = arr[i]
index = i
}
}
const tmp = arr[j]
arr[0] = min;
arr[index] = tmp
}
return arr;
}
console.log(quickSort(arr), 'res')
In the code above i try to sort the array using the next logic:
i compare each array element with the first one and if it is lower than the first then i swap the array elements.
Doing this i don't get the sorted array. Question: What is the issue with my code and how to fix it?
const arr = [5,3,2,6,1];
const quickSort = (arr) => {
for(let j = 0; j < arr.length; j++) {
let index = j;
let min = arr[j];
for(let i = j+1; i < arr.length; i++) {
if(arr[i] < min) {
min = arr[i]
index = i
}
}
let tmp = arr[j]
arr[j] = min;
arr[index] = tmp
}
return arr;
}
Quick sort is a divide and conquer algorithm used for sorting. If you want to view more information about it visit the wikipedia site for quick sort. Your current code does what you told it to do, which is not sorting but as you said it is comparing each element with the first one and if it is smaller it swaps them. Now, if you want to sort an array just use the built-in sort function
arr.sort();
That should sort the array. If you want to built one on your own I would suggest to pick one that best suits you from the long list of sorts.
If you are a beginner, I would suggest you to try Bubble Sort or Selection Sort, but if you feel comfortable with writing code then Quick Sort or even Merge Sort could potentially be more suitable for you.
Revieing your code, it appears that you were trying to implement a Selection sort. This code should help:
const arr = [5,3,2,6,1];
const SelectionSort = (arr) => {
for(let j = 0; j < arr.length; j++) {
let index = null;
let min = arr[j];
for(let i = j; i < arr.length; i++) {
if(arr[i] < min) {
min = arr[i]
index = i
}
}
const tmp = arr[j]
arr[j] = min;
arr[index] = tmp
}
return arr;
}
console.log(SelectionSort(arr), 'res')
Your main mistake in the code was that you started everything from index 0, but you should have initialised everything from j because you are in a loop.

How can I add the numbers in the following code?

I have an array named arr = [[1,2],4] , and for loops to access the numbers. But I can't seem to add the last number. Why is it not working?
let arr = [[1,2],4];
let total = 0;
for(let i = 0; i < arr.length; i++) {
for(let j = 0; j < arr[i].length; j++) {
total += arr[i][j];
}
}
console.log(arr.length) // returns length = 2
console.log(total); // returns total = 3
Your issue is that your array doesn't just consist of only arrays, it consists of both single numbers and nested arrays. As a result, your inner loop won't be able to loop over the number 4 as it is not an array (and so it won't have a .length property).
let arr = [[1,2],4];
// no issues-^ ^-- no `.length` property (inner for loop won't run)
For a problem like this, you can make use of a recursive function, which when you encounter a nested array, you can recall your function to perform the addition for that array.
See example below (and code comments):
function sumNums(arr) {
let total = 0;
for (let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i])) { // If current element (arr[i]) is an array, then call the sumNums function to sum it
total += sumNums(arr[i]);
} else {
total += arr[i]; // If it is not an array, then add the current number to the total
}
}
return total;
}
let arr = [[1,2],4];
console.log(sumNums(arr)); // 7
You can also make use of a recursive call with .reduce() if you would like to take that approach:
const arr = [[1,2],4];
const result = arr.reduce(function sum(acc, v) {
return acc + (Array.isArray(v) ? v.reduce(sum, 0) : v);
}, 0);
console.log(result); // 7
Since the values can be array or numbers, Just add the check before doing the inner loop
if (!Array.isArray(arr[i])) {
total += arr[i];
continue;
}
let arr = [[1,2],4];
let total = 0;
for(let i = 0; i < arr.length; i++) {
if (!Array.isArray(arr[i])) {
total += arr[i];
continue;
}
for(let j = 0; j < arr[i].length; j++) {
total += arr[i][j];
}
}
console.log(arr.length) // returns length = 2
console.log(total);

JavaScript Scope : please explain me why different result in and of loop creating variable

Can you please explain to my why i get to different results;
This is the finished code and the result I wished:
function largest_of_arrs(arr){
var largest_arr = [];
var holder;
var max = 1;
for(var i = 0; i < arr.length; i++){
var sum = 0;
for(var j = 0; j < arr[i].length; j++){
sum += arr[i][j];
if(sum > max) {
max = sum;
largest_arr = arr[i];
}
}
}
return largest_arr;
}
var array_1 = [[1,2,3,4,5],[1,2,2,3,1],[11,12,23,45,88],[20,20,5,5,1]];
largest_of_arrs(array_1);
This gives me the wished result: [11,12,23,45,88]
But when i declare the sum variable outside the for loop like this
function largest_of_arrs(arr){
var largest_arr = [];
var holder;
var max = 1;
var sum = 0;
for(var i = 0; i < arr.length; i++){
for(var j = 0; j < arr[i].length; j++){
sum += arr[i][j];
if(sum > max) {
max = sum;
largest_arr = arr[i];
}
}
}
return largest_arr;
}
var array_1 = [[1,2,3,4,5],[1,2,2,3,1],[11,12,23,45,88],[20,20,5,5,1]];
largest_of_arrs(array_1);
The result is: [20,20,5,5,1]
Can you please explain to me why ?, and how to scope here works?
if possible please with pictures (graphical) ..
Can you please explain to me why?
In the first case, you reset the value of sum to zero on each iteration of the outer loop. In the second case, you don't so sum just keeps accumulating.
and how to scope here works?
Variables declared with var have function scope (or global if declared globally). Your problem isn't to do with scope, it's because of where you assign 0 to sum.
if possible please with pictures (graphical)
Sorry, no pictures. :-(
First Case -
i=0
sum = 0;
j iterates till end of loop
sum = 1+2+3+4+5;
i=1
sum = 0;
j iterates till end of loop
sum = 1+2+2+3+1;
i=2
sum = 0;
j iterates till end of loop
sum = 11+12+23+45+88;
....
Second Case -
i=0
sum = 0;
j iterates till end of loop
sum = 1+2+3+4+5;
i=1
sum = 1+2+3+4+5;
j iterates till end of loop
sum = (1+2+3+4+5)+1+2+2+3+1;
i=2
sum = ((1+2+3+4+5)+1+2+2+3+1);
j iterates till end of loop
sum = ((1+2+3+4+5)+1+2+2+3+1)+11+12+23+45+88;
...
The for statement does not define a scope in javascript, only functions do (as per ES5).
Your problem is because the moment you assign 0 to sum: inside the outer for.

Reading multi-dimensional arrays - Javascript

I'm having some issues on how to read arrays.
console.log(arr[i][j]); -- Can someone explain how the i and j fit into this. I'm printing the array i and j to the console, correct?
function multiplyAll(arr) {
var product = 1;
// Only change code below this line
var i = 0;
var j = 0;
for (i = 0; i < arr.length; i++ ) {
for (j = 0; j < arr[i].length; j++) {
console.log(arr[i][j]);
product *= arr[i][j];
}
}
// Only change code above this line
return product;
}
// Modify values below to test your code
multiplyAll([[1,2],[3,4],[5,6,7]]);
You are printing the j-th element of the i-th array to the console.

finding an array in another Multidimensional array in javascript

I'm writing a simple snakes game using JavaScript and HTML5 canvas.
I have a Multidimensional array that hold snake block like this:
snake=[[1,1],[1,2]];
and set it on arrayMap using (snake.indexOf([i],[j])!=-1) then draw arrayMap on canvas.
for (var i = 0; i < blocksHeightCount; i++) {
for (var j = 0; j < blocksWidthCount; j++) {
if ((snake.indexOf(i,j)!=-1)||
(walls.indexOf(i,j)!=-1)||
(foods.indexOf(i,j)!=-1)) {
arrayMap[i][j]=1;
} else {
arrayMap[i][j]=0;
}
}
}
for (var i = 0; i < blocksHeightCount; i++) {
for (var j = 0; j < blocksWidthCount; j++) {
Block = arrayMap[i][j];
if (Block!=0){
ctx.fillStyle = (Block != 9) ? colors[Block]
: "#bdc3c7";
ctx.fillRect(j * cubeWidth, i * cubeHeight
, cubeWidth-.4,cubeHeight-.4);
}
}
}
the problem is indexOf isn't working when I set array on it!
It works fine when I set indexOf("i,j") but i need it to be array.
please help, thx
First solution : using Array.map
Each element of your arrays snake, walls and foods is an array with 2 elements. So to check if an [x,y] exists in one of the arrays you need a simple way to
compare two arrays [x1, y1] and [x2, y2]. Comparing arrays directly using the operator == will compare their references and not values (Thanks #Elena for the remarque). A way to compare values
would be to affect a hash to each array and compare hashes. By hash I mean a number which is unique for each array of type [x, y]. That could be x * blocksWidthCount + y
in your case and the code will be :
function getHash(x, y){
return x * blocksWidthCount + y;
}
var blockHashes = snake.concat(walls).concat(foods).map(function(cell) {
return getHash(cell[0], cell[1]);
}); // hashes of all blocks in one array
for (var i = 0; i < blocksHeightCount; i++) {
for (var j = 0; j < blocksWidthCount; j++) {
if (blockHashes.indexOf(getHash(i, j)) != -1) {
arrayMap[i][j]=1;
} else {
arrayMap[i][j]=0;
}
}
}
Second Solution Changing the way we see things
Instead of looping over all cells and verifying if every single cell is a block which gives a complexity of O(N * M) (N number of cells and M number of blocks).
We can do better simply by supposing that there is no block and then loop over blocks and mark them as blocks which is in O(N + M) !
function markBlock(cell){
arrayMap[cell[0]][cell[1]] = 1;
}
for (var i = 0; i < blocksHeightCount; i++)
for (var j = 0; j < blocksWidthCount; j++)
arrayMap[i][j] = 0;
snake.forEach(markBlock);
walls.forEach(markBlock);
foods.forEach(markBlock);

Categories

Resources