I am attempting to learn Javascript by implementing Conway's Game of Life but unfortunately, I am stuck right at the beginning.
I have a matrix:
[
[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0]
]
and would like to simulate a border of "1"s which surround the matrix. My final matrix should be:
[
[1,1,1,1,1,1],
[1,0,0,0,0,1],
[1,0,0,0,0,1],
[1,0,0,0,0,1],
[1,0,0,0,0,1],
[1,1,1,1,1,1]
]
So far, I have written the following code:
var matrix = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]];
function addBorder(m) {
var row = []
for (var i=0; i<m[0].length; i++) {
row.push(0);
}
m.splice(0, 0, row);
m.push(row);
for (var i=0; i<m.length; i++) {
m[i].splice(0,0,1);
m[i].push(1);
}
return m;
}
addBorder(matrix).forEach(i => console.log(i.join(',')))
The output matrix is almost what I want, but not quite. However, if I change the second for loop to (var i=0; i<m.length; i++)
, the code produces the right matrix. Unfortunately, I have no idea why it does not work initially but with this altered line of code. Why does it add two items at the first and last loop? I am grateful for any hint!
The reason for the additional 1s in the first and last row is that they are the same row-object. You should avoid putting the same row object twice in your matrix.
So change:
m.splice(0, 0, row);
m.push(row);
to:
m.splice(0, 0, row);
m.push([...row]); // create a copy of row, and push that.
Now when you perform your loop to pre- and postfix a 1, you'll be sure to target a different row object each time.
Unrelated, but m.unshift(row)
would be the same as m.splice(0, 0, row)
.
In a more functional way, without mutating the original array, you could write the function like this:
function addBorder(m) {
return [
Array(m.length+2).fill(1),
...m.map(row => [1, ...row, 1]),
Array(m.length+2).fill(1)
];
}
var matrix = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]];
console.log(addBorder(matrix));
Of course, you can still decide to assign the result to the original matrix variable:
matrix = addBorder(matrix)