Cannot set property '3' of undefined in 2 dimensional array - javascript

I am trying to create a 2 dimensional array but am getting this error.
I loop an object and try to assign them but it won't let me assign a value to the second dimension.
This is what I have:
//this is globally set
var gcollision = new Array();
function create() {
for (var X in sdata) {
X = parseInt(X);
for (var Y in sdata[X]) {
Y = parseInt(Y);
width = parseInt(sdata[X][Y][2]);
height = parseInt(sdata[X][Y][3]);
for (i = X; i != X + width; i++) {
//error occurs here "Uncaught TypeError: Cannot set property '3' of undefined"
gcollision[i][Y] = 1
for (j = Y; j != Y + height; j++) {
gcollision[X][j] = 1
}
}
}
}
How do I make it set the value of properly?
EDIT sdata looks like this:
var sdata = {"4":{"7":["1","7","3","3"]},"3":{"3":["2","8","1","1"]}};

//this is globally set
var gcollision = new Array();
function create(){
for (var X in sdata) {
X = parseInt(X);
for (var Y in sdata[X]) {
Y = parseInt(Y);
width = parseInt(sdata[X][Y][2]);
height = parseInt(sdata[X][Y][3]);
for (i=X; i!= X+width; i++) {
if( typeof gcollision[i] == 'undefined' ) gcollision[i] = new Array();
gcollision[i][Y] = 1
for (j=Y; j!=Y+height; j++) {
if( typeof gcollision[X] == 'undefined' ) gcollision[X] = new Array();
gcollision[X][j] = 1
}
}
}
}
Basically, even though you created your array, those indices do not exist yet, so you cannot reference them as arrays until after you define them as such.
If you set up your for loops a bit more optimally, you don't have to do isset and can just create the gcol[index] = Array(); the right before the inner loop where it is first accessed.

You'll need to initialize the first level of arrays, first.
function create() {
for (var X in sdata) {
X = parseInt(X);
gcollision[X] = [];
for (var Y in sdata[X]) {
Y = parseInt(Y);
width = parseInt(sdata[X][Y][2]);
height = parseInt(sdata[X][Y][3]);
for (i = X; i < X + width; i++) {
gcollision[i][Y] = 1;
for (j = Y; j < Y + height; j++) {
gcollision[X][j] = 1;
}
}
}
}

Related

indicies after 0 are the correct object but show as undefined when accessing

class Space {
constructor(x, y, c = 'grey',c2 = 'darkgrey') {
this.x = x;
this.y = y;
this.w = 10;
this.h = 10;
this.c = c;
this.c2 = c2;
}
draw() {
drawSpace(this.x,this.y,this.c,this.c2)
}
}
// Creates grid for movement
function createGrid() {
for (let i = 0; i < 80; i+=1) {
let tempArr = [];
for (let j = 0; j < 40; j+=1) {
tempArr.push(new Space(i,j));
}
grid.push(tempArr);
}
grid[0][0] = pathfinder;
grid[79][0] = target;
}
//draws grid
grid.forEach(function(e) {
e.forEach(function(f) {
f.draw();
});
});
What's not shown is the implementation of the "pathfinder" and "target" variables. They are also "Space" objects with specific green/red colors respectively.
The issue arises with the line grid[80][0] = target; Where I get an error stating that I cannot set properties of undefined. (setting 0). This is referencing the '0' that should be from the 0th index of the 80th array. When console.log(grid[80][0]); I do get the base Space Object that was set in the original for loop. Why is this happening/how can I set the value of the index to the needed Space object 'target'.
Edit - The
grid[0][0] = pathfinder;
grid[80][0] = target;
is on the first for loop.
Edit 2 - It does it on grid[1][0] as well, I understand that the grid[80][0] doesn't exist as its going 0-79.

How to check if two elements are side by side in multidimentional array in javaScript

i will go straight to the point.. So i have created a multidimentional array and i have it like this:
var arr = [];
for (var i = 0; i < 10; i++) {
var sArr = [];
for (var a = 0; a < 10; a++) {
cell = Object.create(cellObj)
sArr.push(cell);
}
arr.push(sArr);
}
And about the cellObj, i created it like this:
var cellObj = {
state: 0,
img: ""
};
Now that i have everything setup, i generate two images in the multidimentional array like this:
//the array imgs contain two images
for (var l = 0; l < imgs.length; l++) {
var x = Math.floor(Math.random() * arr.length);
var y = Math.floor(Math.random() * arr[x].length);
//here is a test to make sure that the two images are in two separate cells
if (arr[x][y].state === 0) {
arr[x][y].state = 3;
arr[x][y].img = imgs[l];
}
else
{
l--;
}
}
the two images can be on the same row or column with an empty cell between them but i dont want them to be side by side horizontally or vertically.
I hope a nice day to everyone, thank's.
The easiest way to achieve what you're looking for is to eliminate those options up front. In the method below, I'm creating a flat array that contains all positions in your array (I've renamed arr to arrayOfImages for clarity) and naming it coordLookup. Once you place an image, the positions next to it vertically and horizontally are removed from coordLookup in the filter statement. I've increased the number of test images to show that it's maintaining that spacing - just be aware that if you try to place more images than the array has room to accomodate, it will start to fail, so be sure to add error handling for that case.
(To see this in action, open your console and run the code snippet, it should present the completed array as a table.)
var cellObj = {
state: 0,
img: ""
};
var arrayOfImages = [];
for (var i = 0; i < 10; i++) {
var sArr = [];
for (var a = 0; a < 10; a++) {
cell = Object.create(cellObj)
sArr.push(cell);
}
arrayOfImages.push(sArr);
}
var coordLookup = [], i = 10, j = 10 //create coordinate lookup
while(--i > -1){
j = 10
while(--j > -1){
coordLookup.push([i,j])
}
}
var imgs = ['image1.jpg', 'image2.jpg', 'image1.jpg', 'image2.jpg', 'image1.jpg', 'image2.jpg', 'image1.jpg', 'image2.jpg', 'image1.jpg', 'image2.jpg', 'image1.jpg', 'image2.jpg']
for (var l = 0; l < imgs.length; l++) {
let pairIndex = Math.floor(Math.random() * coordLookup.length),
pair = coordLookup[pairIndex],
x = pair[0], y = pair[1]
//insert image
arrayOfImages[x][y].state = 3;
arrayOfImages[x][y].img = imgs[l]
//disable horizontal and vertical neighbor cells
const prevX = x - 1, nextX = x + 1, prevY = y - 1, nextY = y + 1
coordLookup = coordLookup.filter(coordpair => {
const _x = coordpair[0], _y = coordpair[1],
isMatch = (_y == y && _x >= prevX && _x <= nextX) || (_x == x && _y >= prevY && _y <= nextY)
return !isMatch
})
}
//display results
console.table(arrayOfImages.map(row => row.map(cell => JSON.stringify(cell))))

javascript element of array stays unchangeable, even after change value

My problem is this:
Suppose this class, it's an example of my true code:
class TileMap {
constructor ( w, h ) {
this.tiles = [];
// init the matrix
for (var i = 0; i < h; i++) {
var a = [];
for (var j = 0; j < w; j++) {
a.push(0);
}
this.tiles[i] = a;
}
}
setTile (x, y, tile) {
this.tiles[y][x] = tile;
}
doSomething () {
this.setTile(0, 0, 1);
this.setTile(0, 1, 2);
}
}
// What's happening is when I use like this:
var player = {};
player.map = new TileMap(32, 90, 90);
player.map.doSomething();
console.log("before Tile[0][0] = " + player.map.tiles[0][0]);
player.map.setTile(0, 0, 3);
console.log("after Tile[0][0] = " + player.map.tiles[0][0]);
Shows me the follow output:
before Tile[0][0] = 1
after Tile[0][0] = 1
The matrix are modified but turn back to before values.
What should I do? (NOTE I'm not familiar with javascript but with language like C++)
I do not understand what is wrong. I added to your code the player object.
class TileMap{
constructor ( w, h ){
this.tiles = [];
//init the matrix
for (var i = 0; i < h; i++)
{
var a = [];
for (var j = 0; j < w; j++)
a.push(0);
this.tiles[i] = a;
}
}
setTile (x, y, tile){
this.tiles[y][x] = tile;
}
doSomething (){
this.setTile(0,0, 1);
this.setTile(0,1, 2);
}
}
//What's happening is when I use like this:
var player = {};
player.map = new TileMap(32,90,90);
player.map.doSomething();
console.log("before Tile[0][0] = "+player.map.tiles[0][0]);
player.map.setTile(0,0, 3);
console.log("after Tile[0][0] = "+player.map.tiles[0][0]);

JS 2D Array Error: "TypeError: Cannot read property '0' of undefined"

Working on a project for a class and keep getting this error when I want to reference an location in my 2D array.The project is a video game recommender system using pearson correlations. To get the correlations we are pulling results from a database filled usernames, the video game they ranked, and the rank(rating) they gave it. This is then used to create a userArray(array of all users who have ratings) and a rankArray(2D array pictured below with all games and the ratings users have given it) within the generateArrays function.
The error is coming from the line within my sim_pearson function which calculates the actual correlation value. When I try to reference a rating given by a particular user for a particular game, the error arise. I am unsure why as I have referenced the 2D array in a similar way before and had no issue.
Here is my sim_pearson function where the error occurs.
function sim_pearson(rankArray, person1, person2){
var similaritems = [];
for(var i = 0; i <= 9; i++){
if (rankArray[i][person1] !== 0){
if(rankArray[i][person2] !== 0){
similaritems.push(i);
}
}
}
if (similaritems.length === 0){
return 0;
}
console.log(similaritems);
var n = similaritems.length;
var temp1, temp2, sum1, sum2, sum1Sq, sum2Sq, pSum = 0;
for (var x = 0; x <= n; x++){
var sItem = similaritems[x];
temp1 = rankArray[sItem][person1];
temp2 = rankArray[sItem][person2];
sum1 = sum1 + temp1;
sum2 = sum2 + temp2;
sum1Sq = sum1Sq + Math.pow(temp1, 2);
sum2Sq = sum2Sq + Math.pow(temp2, 2);
//sum of products
pSum = pSum + (temp1 * temp2);
}
var num = pSum - (sum1*sum2/n);
var den = Math.sqrt((sum1Sq-Math.pow(sum1, 2)/n)*(sum2Sq-Math.pow(sum2, 2)/n));
if (den === 0){
return 0;
}
var r = num/den;
return r;
}
Here is where I create the arrays:
var userArray = [];
var rankArray = [];
function generateArray(result){
//generate user array
var i,item;
var temp = 0;
for (i in result.rows) {
item = result.rows[i];
var userExists = false;
for (var x = 0; x<=userArray.length; x++){
if(item.username == userArray[x]){
userExists = true;
}
}
if(userExists === false){
userArray.push(item.username);
}
}
for(var y =0; y<10; y++){
rankArray[y] = [];
for(var z = 0; z<userArray.length; z++){
rankArray[y][z] = 0;
}
}
//creating rankarray
var w, item1;
for(w in result.rows) {
item1 = result.rows[w];
for(var k in userArray) {
if (item1.username == userArray[k]) {
temp = k;
}
}
rankArray[(item1.vgnum - 1)][temp] = item1.rank;
}
}
And here is a picture of our arrays when they are created. userArray is first holding all the users, then rankArray which has an array set up in each index for each game(there are only 10) and within that array are the rankings of all the users(0 is user 1, 1 is user 2, etc). After is the similaritems array which just finds the games that two users have both rated.
The line that I am calling sim_pearson from essentially looks like this:
generateArrays(result);
//comparing the first two users
console.log("Pearson value: "+sim_pearson(rankArray, 0, 1);
Really unsure why this error is occuring and why I cannot set a var equal to a location with the rankArray I made like:
temp1 = rankArray[sItem][person1];
Any help would be fantastic!
This line is probably the problem:
for (var x = 0; x <= n; x++){
It should be x < n. Since n = similaritems.length, the indexes of similaritems run from 0 to n-1. So on the last iteration, when you do:
var sItem = similaritems[x];
it sets sItem = undefined. Then you do:
temp1 = rankArray[sItem][person1];
rankArray[undefined] is undefined, so this tries to access undefined[person1], which is not valid.

Creating a 2d array of objects in javascript

I have a javascript object -
cell{xPos, yPos};
I would like to create a 2d array of this object.
cellPrototype = function(x, y) {
this.xPos = x;
this.yPos = y;
}
var cell = new Array();
for(var i=0;i<10;i++)
{
cell[i] = new Array();
for(var j=0;j<10;j++)
{
cell[i][j] = new cellPrototype(i,j);
}
}
This code doesn't work.
Neither does -
var cellPrototype = function(x, y) {
return {
xPos : x;
yPos : y;
}
var cell = new Array();
for(var i=0;i<10;i++)
{
cell[i] = new Array();
for(var j=0;j<10;j++)
{
cell[i][j] = new cellPrototype(i,j);
}
}
So how do I create a 2d array of an object in javascript?
This works fine for me, I'm not sure if that's exactly the output you're looking for, where
Array[x][y] will reference an object with points at x, y.
var Coords = function(x, y) {
return {
"x" : x,
"y" : y
};
};
var Main = [];
for (var i = 0, l = 10; i < l; i++) {
Main[i] = [];
for (var j = 0, l2 = 10; j < l2; j++) {
Main[i][j] = Coords(i, j);
}
}
http://jsfiddle.net/robert/d9Tgb/
You can make a 2d array like so:
var new_array = [];
var arr_length = 10;
for(var i = 0; i < arr_length; ++i){
new_array[i] = [];
}
This post is a bit old, but here is another way to create a 2D array
var arr1=[];
var x=['a','b','c','d'];
var y=[1,2,3,4];
for( var i in x){
arr1.push([x[i],y[i]]); //For x and y of the same length
}
In JavaScript x and y can be objects arrays
jsFiddle It :)
make an empty array and push the child arrays onto it
var array = [];
array.push([1,2,3,4]);
//array[0][0] == 1
or all in one shot
var array = [[1,2,3,4], [1,2,3,4], [1,2,3,4]];

Categories

Resources