0

I am having no luck creating and accessing an array of objects. I'm trying to draw 10 random rectangles on a canvas and store their X,Y, Width and Height in an array to access later.

var square = {cX : 0, cY : 0, W : 200, H : 100}
var squares = []; 
var squaresToMake = 10;
for ( var loopy = 0; loopy < squaresToMake; loopy++ ) {
 square.cX = Math.floor(Math.random() * 20);
 square.cY = Math.floor(Math.random() * 20);
 square.W = Math.floor(Math.random() * 200);
 square.H = Math.floor(Math.random() * 50);
 squares.push(square);
}
var arrayLength = squares.length;
for (var loopy = 0; loopy < arrayLength; loopy++) {
 ctx.rect(squares[loopy].cX, squares[loopy].cY, squares[loopy].W, squares[loopy].H);
 ctx.fill();
}

The result I'm getting is the squares array is full of 10 objects that all have the same values: the last values that were generated from loop that assigns random numbers. Please advise me what I'm doing wrong! Thank you

asked Aug 5, 2018 at 0:35

4 Answers 4

1

You are pushing the same object (square) ten times, because objects are stored/passed by reference. Every time you put new values into 'square' you are just updating the same object. Move "var square" into the loop, so you create a new square each cycle.

answered Aug 5, 2018 at 0:38
Sign up to request clarification or add additional context in comments.

Comments

1

You are pushing the same object to the array. Bring the square object inside the for loop so that new one get created on each iteration. Currently, you will only see the 10 elements that points to same reference, which contains an square object with lastly added values.

var squares = []; 
var squaresToMake = 10;
for ( var loopy = 0; loopy < squaresToMake; loopy++ ) {
 var square = {cX : 0, cY : 0, W : 200, H : 100}
 square.cX = Math.floor(Math.random() * 20);
 square.cY = Math.floor(Math.random() * 20);
 square.W = Math.floor(Math.random() * 200);
 square.H = Math.floor(Math.random() * 50);
 squares.push(square);
}
var arrayLength = squares.length;
for (var loopy = 0; loopy < arrayLength; loopy++) {
 ctx.rect(squares[loopy].cX, squares[loopy].cY, squares[loopy].W, squares[loopy].H);
 ctx.fill();
}
answered Aug 5, 2018 at 0:40

Comments

1

your requirements can be met like this. sometimes, not defining extra variables make the code less error prone.

var squares = [];
var squaresToMake = 10;
for (var i = 0; i < squaresToMake; i++) {
 squares.push({
 cX: Math.floor(Math.random() * 20),
 cY: Math.floor(Math.random() * 20),
 W: Math.floor(Math.random() * 200),
 H: Math.floor(Math.random() * 50)
 });
}
squares.forEach(function(sq) {
 ctx.rect(sq.cX, sq.cY, sq.W, sq.H);
 ctx.fill();
});
answered Aug 5, 2018 at 2:34

Comments

0

Here is a slightly more ES6 approach for the generation of the values:

var squares = []; 
var keys = ['cX', 'cY', 'W', 'H']
var squaresToMake = 10;
const newValue = () => Math.floor(Math.random() * new Date().getMilliseconds())
const newSquare = () => keys.reduce((r,c) => Object.assign({[c]: newValue() }, r), {})
Array.from(new Array(squaresToMake), (x) => squares.push(newSquare()) )
console.log(squares)

answered Aug 5, 2018 at 7:07

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.