"undefined is not an object" when create multidivisional array - javascript

I wrote the code:
var from = 6;
var io_arr = [0, 1, 2, 3];
var mem_arr = [0, 1, 2, 3];
var cpu_arr = [0, 1, 2, 3];
var x = new Array(io_arr.length);
for (var i = 0; i < io_arr.length; i++) {
x[i] = new Array(4);
}
for (var i = 1; i <= io_arr.length; i++) {
for (var j = 0; j <= 3; j++) {
if(j == 0) {
x[i][j] = from + i - 1;
}
if (j == 1) {
x[i][j] = io_arr[i];
}
if (j == 2) {
x[i][j] = mem_arr[i];
}
if (j == 3) {
x[i][j] = cpu_arr[i];
}
}
}
Had the error
TypeError: undefined is not an object (evaluating 'x[i][j] = io_arr[i]')
What's wrong with this? I'm very new to JS, so sorry if the answer is obvious.

My guess:
for (var i = 1; i <= io_arr.length; i++) needs to be: for (var i = 0; i < io_arr.length; i++)
Or is there a specific reason why you modified this in the second for loop?

for (var i = 1; i <= io_arr.length; i++) {
is wrong, the first index is 0 not 1. An you are going too far, as the last index is not the value of io_arr.length but one smaller then the length (because it's starting at 0 ;) )
This should then work:
for (var i = 0; i < io_arr.length; i++) {
I checked the Code by changing this line, and it does not throw any error. This is just some programming basics you will have to get used to

So my original suggestion (in the comments) was to perform both operations in the same loop. That would allow you to get rid of two lines of code. So
var x = new Array(io_arr.length);
for (var i = 0; i < io_arr.length; i++) {
x[i] = new Array(4);
}
for (var i = 1; i <= io_arr.length; i++) {
for (var j = 0; j <= 3; j++) {
if(j == 0) {
x[i][j] = from + i - 1;
}
if (j == 1) {
x[i][j] = io_arr[i];
}
if (j == 2) {
x[i][j] = mem_arr[i];
}
if (j == 3) {
x[i][j] = cpu_arr[i];
}
}
}
would be replaced be
var x = new Array(io_arr.length);
for (var i = 0; i < io_arr.length; i++) {
x[i] = new Array(4);
for (var j = 0; j <= 3; j++) {
if(j == 0) {
x[i][j] = from + i - 1;
}
if (j == 1) {
x[i][j] = io_arr[i];
}
if (j == 2) {
x[i][j] = mem_arr[i];
}
if (j == 3) {
x[i][j] = cpu_arr[i];
}
}
}
The problem is that you want the first row of x to be empty. You can do that in a single loop by adding an if statement inside the loop:
var x = new Array(io_arr.length);
for (var i = 0; i < io_arr.length; i++) {
x[i] = new Array(4);
if (x === 0) continue;
for (var j = 0; j <= 3; j++) {
if(j === 0) {
x[i][j] = from + i - 1;
}
if (j === 1) {
x[i][j] = io_arr[i];
}
if (j === 2) {
x[i][j] = mem_arr[i];
}
if (j === 3) {
x[i][j] = cpu_arr[i];
}
}
}
This should give you your desired answer.
Note that I've changed == to ===, which should always be the preferred choice, because == performs weird conversions, and Javascript purists don't like it.

Related

Why do I get an Uncaught TypeError: property 4 is undefined when looping through a 2d array?

So I am building Tetris. After creating an array, data, I am trying to implement gravity by checking
every string in an array if it's is "full" as well as being able the space below it being empty. However, it is giving me an error that suggests that something is undefined. The I tried a for loop and a for...of loop, as well as Googling it.Why do I get this error, and how can I fix it?
const editor = document.getElementById("edit");
var data = [];
function array(x, text) {
var y = [];
for (var i = 0; i < x - 1; i++) {
y.push(text);
}
return y;
}
for (var i = 0; i < 20; i++) {
data.push(array(10, "b"));
}
function draw() {
var j;
var i;
var dataOut = data;
for (i = 0; i < data.length; i++) {
for (j = 0; j < data[i].length; j++) {
if (data[i][j] == "a" && data[i + 1][j] == "b") {
if (i < data.length - 1) {
dataOut[i][j] = "b";
dataOut[i + 1][j] = "a";
}
}
}
}
data = dataOut;
console.log(data);
requestAnimationFrame(draw);
}
data[0][4] = "a";
requestAnimationFrame(draw);
with for-of-loop you iterate only objects/values of array and not indexes.
use only for-loop in order to use indexes
const editor = document.getElementById("edit");
var data = [];
function array(x, text) {
var y = [];
for (var i = 0; i < x - 1; i++) {
y.push(text);
}
return y;
}
for (var i = 0; i < 20; i++) {
data.push(array(10, "b"));
}
function draw() {
var dataOut = data;
for (let i = 0; i < data.length - 1; i++) { // logical error here
for (let j = 0; j < data.length; j++) {
if (data[i][j] == "a" && data[i + 1][j] == "b") {
if (i < data.length - 1) {
dataOut[i][j] = "b";
dataOut[i + 1][j] = "a";
}
}
}
}
data = dataOut;
console.log(data);
requestAnimationFrame(draw);
}
data[0][4] = "a";
requestAnimationFrame(draw);
A simple example of for-of-loop
const arr = ["aa","bb"]
for(let a of arr) console.log(a);
// will print
/*
aa
bb
*/
for(let a = 0; a < arr.length; a++) console.log(a);
// will print
/*
0
1
*/

How many times needed to Sort a number in an Array Javascript

I want to count how many times needed for an array to be sorted
var array = [4,2,3,1]
var yourCounter = 0;
for (var i = 0; i < array.length; i++) {
for (var j = 1; j < array.length-j; j++)
if (array[j - 1] > array[j]) {
yourCounter++;
} }
it will return 4 , it should be 5
but if I input array [1,2,3] will correctly return 0 , and if I input array [3,2,1] it will correctly return 3
You could take the given code and swap the values while counting.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
// Swap adjacent elements if they are in decreasing order
if (a[j] > a[j + 1]) {
swap(a[j], a[j + 1]);
}
}
}
var array = [4, 2, 3, 1],
counter = 0,
i, j, n = array.length;
for (i = 0; i < n; i++) {
for (j = 0; j < n - 1; j++) {
if (array[j] > array[j + 1]) {
[array[j + 1], array[j]] = [array[j], array[j + 1]];
++counter;
}
}
}
console.log(counter);
console.log(array);
I found the solution
var a = [4,2,3,1]
function sortArray(a){
let swapCount = 0;
let swapOccurred = true;
let index = 0;
while (swapOccurred == true && index < a.length){
swapOccurred == false;
if (a[index] > a[index+1]){
let holder = a[index]
a[index] = a[index+1];
a[index+1] = holder;
swapOccurred == true;
swapCount ++;
index = -1;
}
index ++
}
function countSwaps(a) {
let swapCount = 0;
[a, swapCount] = sortArray(a)
console.log(swapCount)
}
return [a, swapCount]
}

Print prime numbers between 0 and 100

I'm trying to print all prime number between 0 and 100, but when executing this code the browser's tab just outputs nothing!!
for(var i = 2; i < 100; i++)
{
var prime = [];
for(var j = 0; j <= i; j++)
{
var p = i % j;
}
if(p != 0) prime.push(i);
else continue;
}
for(var k = 0; k < prime.length; k++)
{
document.writeln(prime[k], "<br>");
}
Try this one. I have also optimise the code (you only need to check upto sqrt(i) ).
var prime = [];
prime.push(2); //smallest prime
var flag = 0;
for(var i = 3; i < 100; i=i+2) //skip all even no
{
for(var j = 3; j*j <= i; j=j+2) //check by upto sqrt(i), skip all even no
{
if(i % j == 0) {
flag = 0;break; //not a prime, break
}
flag = 1;
}
if (flag == 1) prime.push(i); //prime, add to answer
}
for(var k = 0; k < prime.length; k++)
{
document.writeln(prime[k], "<br>");
}
Because you blank your list of primes EVERY loop cycle, move it outside the for loop
You need to make your variable prime outside of your loop
This is the code you have re-written
var prime = [];
for(var i = 2; i < 100; i++)
{
for(var j = 0; j <= i; j++)
{
var p = i % j;
}
if(p != 0) prime.push(i);
else continue;
}
for(var k = 0; k < prime.length; k++)
{
document.writeln(prime[k], "<br>");
}
I'm a fan of the sieve of Eratosthenes.
The following code should do what you wanted.
var prime = Array(101).fill(true);
for (var i = 2; i < 100; ++i){
if (prime[i]){
document.writeln(i, "<br>");
for (var j = i*i; j < 100; j += i){
prime[j] = false;
}
}
}
Or since it's only up to 100 you could just manually type the list (but, hey where's the learning if you do it that way?).
(1) Move prime outside the for loop, (2) start j at 2 and end when j < i, (3) check when p == 0 with a boolean flag and break inner loop.
var prime = []; //put prime out here so it does not reassign
for(var i = 2; i < 100; i++)
{
var isPrime = true;
for(var j = 2; j < i; j++) //start j at 2
{
var p = i % j;
if(p == 0)
{
isPrime = false;
break;
}
}
if(isPrime) prime.push(i);
}
for(var k = 0; k < prime.length; k++)
{
document.writeln(prime[k], "<br>");
}

How to program Pascal's Triangle in Javascript - confusion re Arrays

I'm having a little trouble with my attempt at this problem. Code Below:
function pasc(n){
var result = [[1]];
for (var row = 1; row < n; row++){
for (var col = 1; col <= row; col++){
result[row][col] = result[row - 1][col] + result[row - 1][col - 1];
}
}
return result;
}
pasc(10)
for (var i = 0; i < result.length; i++){
document.write(result[i]+"<br>");
}
It seems the problem hinges on assigning values to an array using an expression like myArray[1][1] = "foo"
I'm confused about this because I can do this: var myArray = []; myArray[4] = "foo" which seems to suggest that an element can be created at an arbitrary position in a 1 dimensional array, but not with 2 dimensions.
Any help with clearing up my misconceptions appreciated.
The Pascal's Triangle can be printed using recursion
Below is the code snippet that works recursively.
We have a recursive function pascalRecursive(n, a) that works up till the number of rows are printed. Each row is a element of the 2-D array ('a' in this case)
var numRows = 10,
triangle,
start,
stop;
// N is the no. of rows/tiers
// a is the 2-D array consisting of the row content
function pascalRecursive(n, a) {
if (n < 2) return a;
var prevRow = a[a.length-1];
var curRow = [1];
for (var i = 1; i < prevRow.length; i++) {
curRow[i] = prevRow[i] + prevRow[i-1];
}
curRow.push(1);
a.push(curRow);
return pascalRecursive(n-1, a); // Call the function recursively
}
var triangle = pascalRecursive(numRows, [[1]]);
for(var i = 0; i < triangle.length; i++)
console.log(triangle[i]+"\n");
JavaScript doesn't have two-dimensional arrays. What it does have is arrays that happen to contain other arrays. So, yes, you can assign a value to any arbitrary position in an array, and the array will magically make itself big enough, filling in any gaps with 'undefined'... but you can't assign a value to any position in a sub-array that you haven't explicitly created yet. You have to assign sub-arrays to the positions of the first array before you can assign values to the positions of the sub-arrays.
Replacing
for (var row = 1; row < n; row++){
for (var col = 1; col <= row; col++){
with
for (var row = 1; row < n; row++){
result[row] = [];
for (var col = 1; col <= row; col++){
should do it. Assuming all of your indexing logic is correct, anyway. You've got some problems there, too, since your initial array only contains a single value, so result[row][col] = result[row - 1][col] + result[row - 1][col - 1]; is accessing at least one cell that has never been defined.
Thanks Logan R. Kearsley. I have now solved it:
function pasc(n){
var result = [];
result[0] = [1];
result[1] = [1,1];
for (var row = 2; row < n; row++){
result[row] = [1];
for (var col = 1; col <= row -1; col++){
result[row][col] = result[row-1][col] + result[row-1][col-1];
result[row].push(1);
}
}
return result;
}
for (var i = 0; i < pasc(10).length; i++){
document.write(pasc(10)[i]+"<br>");
console.log(pasc(10)[i]+"<br>");
}
you can create Pascal's triangle using below code:
function pascal(n) {
var arr = [];
if (n == 1) {
arr[0] = [];
arr[0][0] = 1;
} else if (n == 2) {
arr[0] = [];
arr[0][0] = 1;
arr[1] = [];
arr[1][0] = 1;
arr[1][1] = 1;
} else if (n > 2) {
arr[0] = [];
arr[1] = [];
arr[0][0] = 1;
arr[1][0] = 1;
arr[1][1] = 1;
for (i = 2; i < n; i++) {
arr[i] = [];
arr[i][0] = 1;
for (j = 1; j < i; j++) {
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
}
arr[i][j] = 1;
}
}
console.log(arr);
for (i = 0; i < arr.length; i++) {
console.log(arr[i].join(' '))
}
}
function pascal(n) {
var arr = [];
if (n == 1) {
arr[0] = [];
arr[0][0] = 1;
} else if (n == 2) {
arr[0] = [];
arr[0][0] = 1;
arr[1] = [];
arr[1][0] = 1;
arr[1][1] = 1;
} else if (n > 2) {
arr[0] = [];
arr[1] = [];
arr[0][0] = 1;
arr[1][0] = 1;
arr[1][1] = 1;
for (i = 2; i < n; i++) {
arr[i] = [];
arr[i][0] = 1;
for (j = 1; j < i; j++) {
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
}
arr[i][j] = 1;
}
}
console.log(arr);
for (i = 0; i < arr.length; i++) {
console.log(arr[i].join(' '))
}
}
pascal(5)
This function will calculate Pascal's Triangle for "n" number of rows. It will create an object that holds "n" number of arrays, which are created as needed in the second/inner for loop.
function getPascalsTriangle(n) {
var arr = {};
for(var row = 0; row < n; row++) {
arr[row] = [];
for(var col = 0; col < row+1; col++) {
if(col === 0 || col === row) {
arr[row][col] = 1;
} else {
arr[row][col] = arr[row-1][col-1] + arr[row-1][col];
}
}
}
return arr;
}
console.log(getPascalsTriangle(5));
Floyd triangle
You can try the following code for a Floyd triangle
var prevNumber=1,i,depth=10;
for(i=0;i<depth;i++){
tempStr = "";j=0;
while(j<= i){
tempStr = tempStr + " " + prevNumber;
j++;
prevNumber++;
}
console.log(tempStr);
}
You can create arbitrary 2d arrays and store it in there and return the correct Pascal.
JavaScript does not have a special syntax for creating multidimensional arrays. A common workaround is to create an array of arrays in nested loops.
source
Here is my version of the solution
function pascal(input) {
var result = [[1], [1,1]];
if (input < 0) {
return [];
}
if (input === 0) {
return result[0];
}
for(var j = result.length-1; j < input; j++) {
var newArray = [];
var firstItem = result[j][0];
var lastItem = result[j][result[j].length -1];
newArray.push(firstItem);
for (var i =1; i <= j; i++) {
console.log(result[j][i-1], result[j][i]);
newArray.push(sum(result[j][i-1], result[j][i]));
}
newArray.push(lastItem);
result.push(newArray);
}
return result[input];
}
function sum(one, two) {
return one + two;
}
Here is the code i created for pascal triangle in javascript
'use strict'
let noOfCoinFlipped = 5
let probabiltyOfnoOfHead = 2
var dataStorer = [];
for(let i=0;i<=noOfCoinFlipped;i++){
dataStorer[i]=[];
for(let j=0;j<=i;j++){
if(i==0){
dataStorer[i][j] = 1;
}
else{
let param1 = (j==0)?0:dataStorer[i-1][j-1];
let param2 = dataStorer[i-1][j]?dataStorer[i-1][j]:0;
dataStorer[i][j] = param1+param2;
}
}
}
let totalPoints = dataStorer[noOfCoinFlipped].reduce((s,n)=>{return s+n;})
let successPoints = dataStorer[noOfCoinFlipped][probabiltyOfnoOfHead];
console.log(successPoints*100/totalPoints)
Here is the link as well
http://rextester.com/TZX59990
This is my solve:
function pascalTri(n){
let arr=[];
let c=0;
for(let i=1;i<=n;i++){
arr.push(1);
let len=arr.length;
if(i>1){
if(i>2){
for(let j=1;j<=(i-2);j++){
let idx=(len-(2*i)+j+2+c);
let val=arr[idx]+arr[idx+1];
arr.push(val);
}
c++;
}
arr.push(1);
}
}
return arr;
}
let pascalArr=pascalTri(7);
console.log(pascalArr);
here is the pattern for n = 3
#
##
###
here is js code to print this.
function staircase(n) {
for(var i=0 ; i<n ; i++) {
for(var j=n-1 ; j>i ; j--)
process.stdout.write(" ");
for(var k=0 ; k<=i; k++) {
process.stdout.write("#");
}
process.stdout.write("\n");
}
}
class PascalTriangle {
constructor(n) {
this.n = n;
}
factoriel(m) {
let result = 1;
if (m === 0) {
return 1;
}
while (m > 0) {
result *= m;
m--;
}
return result;
}
fill() {
let arr = [];
for (let i = 0; i < this.n; i++) {
arr.push([]);
}
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j <= i; j++) {
arr[i].push(this.factoriel(i) / (this.factoriel(j) * this.factoriel(i - j)));
}
}
return arr;
}
}
var m = prompt("enter number:");
var arrMain = new Array();
for (var i = 0; i < m; i++) {
arrMain[i] = [];
}
for (var i = 0; i < m; i++) {
if (i == 0) {
arrMain[i] = [1];
} else if (i == 1) {
(arrMain[i]) = [1, 1];
} else {
for (var j = 0; j <= i; j++) {
if (j == 0 || j == arrMain[i - 1].length) {
arrMain[i][j] = 1;
} else {
arrMain[i][j] = arrMain[i - 1][j] + arrMain[i - 1][j - 1];
}
}
}
document.write(arrMain[i] + "<br>");
}
This is my take on this problem by gaining access to the previous row.
const generate = numRows => {
const triangle = [[1]]
for (let i = 1; i < numRows; i++) {
// Previous row
const previous = triangle[i - 1]
// Current row
const current = new Array(i + 1).fill(1)
// Populate the current row with the previous
// row's values
for (let j = 1; j < i; j++) {
current[j] = previous[j - 1] + previous[j]
}
// Add to triangle result
triangle.push(current)
}
return triangle
}

Array size 114467 good, 114468 not work

I have a strange problem with my alghoritm, which work if array size less than 114468 and doesn't work if more than 114468. Browse with google chrome. Can't understand why =\ Here is the code:
Generate array:
var arr = [];
var res = [];
for (var i = 114467; i > 0; i--) {
arr.push([i - 1, i]);
}
Find first elem in array to sort:
for (var i = 0, j = arr.length; i < j && res.length == 0; i++) {
var found = false;
for (var m = 0; m < j; m++) {
if (i == m || arr[i][0] == arr[m][1] || arr[i][1] == arr[m][0]) {
found = true;
break;
}
if (!found) {
res.push(arr[m]);
arr.splice(m, 1);
}
}
}
Sorting:
do {
for (var i = 0, j = arr.length; i < j; i++) {
var resLength = res.length - 1;
if (arr[i][1] == res[resLength][0] || arr[i][0] == res[resLength][1]) {
res.push(arr[i]);
arr.splice(i, 1);
break;
}
}
} while (arr.length > 0);
On the step sorting it stops to work.
All code:
var t = function () {
var arr = [];
var res = [];
for (var i = 114467; i > 0; i--) {
arr.push([i - 1, i]);
}
var startsec = new Date().getSeconds();
var startmilsec = new Date().getMilliseconds();
document.write(startsec + '.' + startmilsec + '<br>');
for (var i = 0, j = arr.length; i < j && res.length == 0; i++) {
var found = false;
for (var m = 0; m < j; m++) {
if (i == m || arr[i][0] == arr[m][1] || arr[i][1] == arr[m][0]) {
found = true;
break;
}
if (!found) {
res.push(arr[m]);
arr.splice(m, 1);
}
}
}
do {
for (var i = 0, j = arr.length; i < j; i++) {
var resLength = res.length - 1;
if (arr[i][1] == res[resLength][0] || arr[i][0] == res[resLength][1]) {
res.push(arr[i]);
arr.splice(i, 1);
break;
}
}
} while (arr.length > 0);
var stopsec = new Date().getSeconds();
var stopmilsec = new Date().getMilliseconds();
document.write(stopsec + '.' + stopmilsec + '<br>');
var executionTime = (stopsec - startsec).toString() + "s" + (stopmilsec - startmilsec).toString() + "'ms";
document.write(executionTime + '<br>');
} ();
Do i get my memory limit?
Alright, I isolated the problem. It seems that splice(0,1) slows down astronomically when the array size increases from 114467 to 114468.
Using this custom benchmark:
var t;
function startBench(){t=new Date().getTime();}
function stopBench(){console.log(new Date().getTime()-t);}
var arr=[];
for (var i = 114467; i > 0; i--) {
arr.push([i - 1, i]);
}
var arr2=[];
for (var i = 114468; i > 0; i--) {
arr2.push([i - 1, i]);
}
startBench();
for(i=0;i<1000;i++){
arr.splice(0,1);
}
stopBench();
startBench();
for(i=0;i<1000;i++){
arr2.splice(0,1);
}
stopBench();
I get 3 ms for 114467 and 2740ms for 114468 on Chrome (1000 iterations), but 170 each on Firefox. Maybe you ought to be using a different way to remove elements? Using a variant of bubble sort may work better.
I've submitted a bug report on this. Looking at the reply, it seems to be a valid bug. Hopefully it'll be fixed.

Categories

Resources