当我特别说我不希望它通过引用传递数组
Array being passed by reference when I specifically say I don't want it to
我正在编写一个函数来计算矩阵的行列式。算法本身是无关紧要的,但是如果你有兴趣,可以在this page.
的底部找到它
function det(matrix) {
var dim = validate(matrix); // this function checks if it's an actual matrix and returns its dimensions as [rows, columns]
if(dim && dim[0] === dim[1]) {
var ord = dim[0];
if(ord === 2) {
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; // easy
} else {
var r = 0;
for(var i = 0; i < ord; i++) { // using the first row
var elem = matrix[i][0],
mod = Math.pow(-1, i + 2);
minor = matrix.slice(0);
console.log(ord);
minor.splice(i, 1); // remove the ith column
for(var j = 0; j < ord - 1; j++) {
minor[j].splice(0, 1); // remove the first row
}
r += elem * mod * det(minor);
}
return r;
}
} else {
return false;
}
}
有一个问题:我有一个数组 matrix
,我想一直表示原始矩阵,即我不想修改它。当我复制它时,我写 var minor = matrix.slice(0);
来创建一个新数组并停止 matrix
通过引用传递。当然这意味着 minor
是一个单独的对象?显然不是。我没有在 else
分支的任何进一步位置引用 matrix
,但是,在某个地方,它被修改了。通过 bruteforceesque console.log
ging,我将范围缩小到这一行:
minor[j].splice(0, 1); // remove the first row
但是为什么呢?为什么这一行绝不会引用 matrix
最终会改变它的值?当然它应该只改变 minor
的值吗?我该怎么做才能解决这个问题?
Javascript 数组是一维的——你的矩阵是数组的数组。当您调用 slice
时,您创建了一个浅拷贝。也就是说,您正在创建一个新的外部数组,其中包含完全相同的内部数组。您想制作一个深拷贝,同时创建新的内部数组。
function cloneMatrix (matrix) {
return matrix.map(function(sub) { return sub.slice(0); });
}
基于这条线:
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; // easy
我推断数组中每一项的值是另一个数组。
所以:
matrix
是一个值为 "Reference to some array" 的变量
minor
是一个值为 "Reference to an array that is a duplicate of the first array" 的变量
matrix[0]
是一个值 "Reference to another array"
minor[0]
是一个变量,它是 matrix[0]
的副本,因此它是对同一数组的引用。 (同样适用于彼此的索引)。
您需要复制 所有 个数组。
我正在编写一个函数来计算矩阵的行列式。算法本身是无关紧要的,但是如果你有兴趣,可以在this page.
的底部找到它function det(matrix) {
var dim = validate(matrix); // this function checks if it's an actual matrix and returns its dimensions as [rows, columns]
if(dim && dim[0] === dim[1]) {
var ord = dim[0];
if(ord === 2) {
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; // easy
} else {
var r = 0;
for(var i = 0; i < ord; i++) { // using the first row
var elem = matrix[i][0],
mod = Math.pow(-1, i + 2);
minor = matrix.slice(0);
console.log(ord);
minor.splice(i, 1); // remove the ith column
for(var j = 0; j < ord - 1; j++) {
minor[j].splice(0, 1); // remove the first row
}
r += elem * mod * det(minor);
}
return r;
}
} else {
return false;
}
}
有一个问题:我有一个数组 matrix
,我想一直表示原始矩阵,即我不想修改它。当我复制它时,我写 var minor = matrix.slice(0);
来创建一个新数组并停止 matrix
通过引用传递。当然这意味着 minor
是一个单独的对象?显然不是。我没有在 else
分支的任何进一步位置引用 matrix
,但是,在某个地方,它被修改了。通过 bruteforceesque console.log
ging,我将范围缩小到这一行:
minor[j].splice(0, 1); // remove the first row
但是为什么呢?为什么这一行绝不会引用 matrix
最终会改变它的值?当然它应该只改变 minor
的值吗?我该怎么做才能解决这个问题?
Javascript 数组是一维的——你的矩阵是数组的数组。当您调用 slice
时,您创建了一个浅拷贝。也就是说,您正在创建一个新的外部数组,其中包含完全相同的内部数组。您想制作一个深拷贝,同时创建新的内部数组。
function cloneMatrix (matrix) {
return matrix.map(function(sub) { return sub.slice(0); });
}
基于这条线:
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; // easy
我推断数组中每一项的值是另一个数组。
所以:
matrix
是一个值为 "Reference to some array" 的变量
minor
是一个值为 "Reference to an array that is a duplicate of the first array" 的变量
matrix[0]
是一个值 "Reference to another array"minor[0]
是一个变量,它是matrix[0]
的副本,因此它是对同一数组的引用。 (同样适用于彼此的索引)。
您需要复制 所有 个数组。