Changing one cell in multidimensional array updates entire column - javascript

When creating a new multidimensional array in Chrome's console like this:
var array = Array(10).fill(Array(10).fill(false));
the array looks as expected (inspect with console.table):
But when trying to change only one cell in the array: array[5][5] = true; something strange happens:
I have been banging my head against the wall for sometime because of this, but can't figure it out. Could this be a bug since Array.fill is an experimental/new feature?

It's because you actually only created two arrays. You created an inner array with 10 elements and then an outer array that has 10 elements, each of which reference the same inner array. When you change an element of the inner array and then look at the outer array, you'll see the same change in the inner array repeated 10 times.
Create your outer array with a loop instead so that a new inner array is created for every element of your outer loop.

Related

Removing duplicate random numbers from array

Okay so I'm looping through all the elements on the page (3) that have the class 'possible'. Then I'm creating a variable called 'other' that randomly gets a value from the array otherAnswers. Then I'm taking those values and putting them into the respected elements as text. Only thing is, most of the time the loop selects the same variable from the otherAnswers array (sometimes once, sometimes twice, others three, and rarely none of the time). How do I make sure that once the .each loops through one of the values in the array, it doesn't get it again?
$('.possible').each(function(i, obj) {
var other = otherAnswers[Math.floor(Math.random()*otherAnswers.length)];
$(this).text(other);
//otherAnswers.splice(this);
});
I've tried the commented piece of code but that just removes the values so they don't show up on my page. I have a feeling that it has something to do with the variable 'i' in the function but i'm not sure.
You can do this by taking the following steps:
Before looping, take a copy of the otherAnswers array, to avoid that you destroy it with what follows. For instance, with spread syntax:
var remainingAnswers = [...otherAnswers];
Then -- still before the loop -- shuffle the copied array randomly. Take the shuffle code from here.
shuffle(remainingAnswers);
Finally, inside your loop, access the values from that shuffled array, using the index i you already have:
var other = remainingAnswers[i];

JS is changing 2d-array values, might it be another function interfering?

Short summary: I have written some code that fills up a 2-dimensional array. When I display this array, everything is perfect. Now I give this 2d-array as a parameter to a function. When I call the function inside of
document.getElementById('output').innerHTML = myFunction(int, array);
it shows exactly the right values. However, I don't want to display them, I want to further use them. As the function returns an array (one dimensional), I tried
var my_result_array = myFunction(int, array);
I have also tried push() and pre-defined arrays or accessing just single elements.
The thing is, as soon as I have the function called in my document, the array I am giving to the function as a parameter is changing! I took care that there are no similiar names, but I just can`t figure out, why it is always changing my parameter array, therefore destroying the calculation but working fine if I use it in the document.getElementbyId part.
Any suggestions?
Edit for more code:
I try to keep it short and explainatory. I am creating an empty array with a dimension given by mat_dimension_js
var berechnungs_array = new Array(mat_dimension_js);
for (var i = 0; i < mat_dimension_js; i++){
berechnungs_array[i] = new Array(mat_dimension_js);
}
I then fill this array up with values. If I print the array, everything is fine, the values are where they belong. I then feed this array to myFunction()
Sorry for the mess, I have also tried it without creating an array A again.
I then try to grab the output of myFunction() as told above, but as soon as I do that, somehow the array I have given as a parameter changes.
Arrays in JavaScript are passed by reference, meaning that any changes you do to the array passed inside the function will also be saved in the actual array.
In addition, A = mat_array; does not create a copy of mat_array, but another pointer to it (meaning that both variables refer to the exact same array object internally).
To properly make a copy of a 1D array, calling .slice(0) should do the trick. However, for 2D arrays, you need to do this recursively.
See Javascript passing arrays to functions by value, leaving original array unaltered
What is the most efficient way to deep clone an object in JavaScript?

Google Chrome Console not displaying correct data after removing array element with splice

After doing this:
var collection = ['foo', 'bar', 'john'];
console.log(collection);
collection.splice(0,1)
console.log(collection);
I get this
Why does the Chrome console display only two elements instead of all three before the splice?
tl;dr: Because variables only hold references to objects and the console doesn't deep-clone when displaying an object.
The collection variable refers to your Array, since Arrays are Objects. In JavaScript, variables only hold references to objects.
When you mutate your collection array, the collection variable refers/points to the changed array.
When you click that small arrow icon to expand your array in the console, it reads the logged variable again; which has now changed.
The console doesn't deep-clone an object before displaying it.
the result is correct.
splice(x,y) method removes element starting from x index and y specifies number of elements to remove ie; 1 element in your case.
the thing to remember is splice alters your original array.

ReactJS - Can anyone explain how and why this state is being altered?

I am attempting to make Conway's Game of Life with React. I have an array of boolean values representing the grid in state, and then render an "alive" or "dead" cell for true or false values.
The solution I came up with for counting the surrounding number of "alive" neighbours to determine whether a cell is alive or dead in the next generation includes treating corner and edge cells separately from the rest of the middle cells.
In order to do this, I tried making a copy of the grid array and set the elements representing the corner and edge cells to null after counting their neighbours. Then, I was going to iterate over the remaining middle cells and count their surrounding neighbours.
However, after changing elements to null in the copy of the grid, the original grid in state is also changing. Can anyone explain this behaviour?
console.log(this.state.grid[topLeftCorner]); // false
innerSquare[topLeftCorner] = null;
console.log(this.state.grid[topLeftCorner]); // null
https://codepen.io/Egeroth/pen/jaeYwR
When you assign a existing array to another variable, you do not get a copy, simply two variables which point to the same array. If you want to create a separate copy then consider using array.slice() and see Copying array by value in JavaScript for more details.
In the countNeighbours() method you are creating copy of the gird in a wrong way:
let innerSquare = this.state.grid;
This will copy only reference to the grid, not clone it.
You should write: let innerSquare = this.state.grid.slice(0); instead.
Adding .slice(0) will actually clone the grid into a new array.

Chrome console logging - Javascript

I'm wondering, why do some elements appear like an array and others like HTMLSpanElement. I've attached a picture as I'm not sure how to describe this otherwise.
The following log is made via
log(returner);
log(returner[0]);
Is returner a jQuery object as a result of $() ? $() will always return an array, even if there is one or zero elements inside of it. Without specifying an index in your first console.log, the entire contents of the array are outputted. In the second console.log, you include an array index, so only the element matching that index is outputted.
Because the element that appears like an array IS an array - it's an array of DOM element objects (HTMLSpanElement, etc).
When you log the first element of the array with returner[0], that element is a DOM object, so it logs it as an object.
Because (it looks like) returner is not an element, but an array of elements.

Categories

Resources