我在javascript中创建一个2D矩阵,其中该矩阵中的每个元素都是一个空数组。
问题是,每当我尝试推送到矩阵中的一个元素时,推送就会应用于整个矩阵,而不是特定元素。
以下是代码:
function createMatrix(numrows, numcols, initialValue = []) {
var matrix = []; var row = [];
while (numcols--) row[row.length] = initialValue;
while (numrows--) matrix[matrix.length] = row.slice();
return matrix;
};
function printMatrix(matrix) {
var output = '';
for (var i = 0; i < matrix.length; i++) {
output += '[';
for (var j = 0; j < matrix[i].length; j++) {
output += ' ' + matrix[i][j];
}
output += ' ]\n';
}
console.log(output);
};
// Example code
var A = createMatrix(3,6, []);
printMatrix(A)
// This is the output:
// [ ]
// [ ]
// [ ]
// For example, we now try to add number 7 to the empty array at [1][2]
A[1][2].unshift(7);
// Let's see how the matrix looks like:
printMatrix(A)
// [ 7 7 7 7 7 7 ]
// [ 7 7 7 7 7 7 ]
// [ 7 7 7 7 7 7 ]
以上矩阵是错误的。它不是仅将推送应用于单个元素,而是应用于整个矩阵。换句话说,正确的输出应如下所示:
// [ ]
// [ 7 ]
// [ ]
非常感谢您的帮助。谢谢。
答案 0 :(得分:0)
您可以使用slice作为行元素来获取独立元素。
while (numrows--) matrix[matrix.length] = row.map(a => a.slice());
// ^^^^^^^^^^^^^^^^^^^
function createMatrix(numrows, numcols, initialValue = []) {
var matrix = []; var row = [];
while (numcols--) row[row.length] = initialValue;
while (numrows--) matrix[matrix.length] = row.map(a => a.slice());
return matrix;
};
function printMatrix(matrix) {
var output = '';
for (var i = 0; i < matrix.length; i++) {
output += '[';
for (var j = 0; j < matrix[i].length; j++) {
output += ' ' + matrix[i][j];
}
output += ' ]\n';
}
console.log(output);
};
// Example code
var A = createMatrix(3,6, []);
printMatrix(A)
// This is the output:
// [ ]
// [ ]
// [ ]
// For example, we now try to add number 7 to the empty array at [1][2]
A[1][2].unshift(7);
// Let's see how the matrix looks like:
printMatrix(A)
答案 1 :(得分:0)
第一个问题 是您尝试使用以下行将相同初始数组initialValue
的引用分配给每个列:
while (numcols--) row[row.length] = initialValue; // <----
这就是为什么所有列都填充相同的值。 第一个问题的解决方案是:
while (numcols--) row[row.length] = initialValue.slice();
第二个问题 :如果您的数组包含嵌套数组,则“clone”将包含对旧数组的引用。
这是在这一行的矩阵行上发生的情况:
while (numrows--) matrix[matrix.length] = row.slice(); // <---
第二个问题的解决方案是使用Array.protottype.map()
函数克隆所有嵌套数组:
while (numrows--) matrix[matrix.length] = row.map(function(arr){ return arr.slice(); });
现在,您将获得所需的输出:
A[1][2].unshift(7);
[ ]
[ 7 ]
[ ]
答案 2 :(得分:0)
感谢您的评论和答案。非常感谢。
我也得出了相同的结论,问题是由于'slice()'导致的浅拷贝。这是一个更简单的实现,可以解决问题,以防将来有人需要它:
function createMatrix(dimensions) {
var matrix = [];
for (var i = 0; i < dimensions[0]; ++i)
matrix[matrix.length] = (dimensions.length == 1 ? [] : createMatrix(dimensions.slice(1)));
return matrix;
};