You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中使用slice()为何仍修改了原二维数组?

问题:高斯消元法中slice()复制二维数组后原数组仍被修改的原因及解决办法

我第一次用TypeScript写高斯消元(Gauss Jordan Elimination)代码,知道slice()方法能返回数组副本,所以用const input = linsys.slice()复制输入的二维数组linsys,想只修改副本、保留原数组,但控制台打印发现原数组linsys也被修改了。以下是代码片段:

class ChapterOne {
    
    // Gauss Jordan Elimination
    // Notes: Only solve system of linear equation with one solution
    static gaussJordanElim( linsys : number[][] ) {
        const numOfEquation = linsys.length
        const numOfUnknown = linsys[0].length - 1
        if (numOfUnknown > numOfEquation) return 'This System of Linear Equation either have no solution or have infinite solutions'
        
        // I slice it here.
        const input = linsys.slice()
        const length = input.length
        // pointer = i, row to operate = j, column to operate = k
        for (let i = 0; i < length; i += 1) {
            if (input[i][i] === 0) return 'Mathematical Error! Cannot divide by zero'
            for (let j = 0; j < length; j += 1) {
                if (i !== j) {
                    const ratio = input[j][i] / input[i][i]
                    for (let k = 0; k < length + 1; k += 1) {
                        input[j][k] = input[j][k] - ratio * input[i][k]
                    }
                }
            }
        }
        // I Checked it here
        console.log(input)
        console.log(linsys)

        const output = input.map((row, pointer) => row[length] / row[pointer])
        return output
    }
}

原因解释

slice()方法对二维数组做的是浅拷贝:它只会复制外层数组的结构,而数组里的每个子数组(也就是每一行)都是引用类型,input和原数组linsys指向的是同一个子数组对象。当你修改input[j][k]时,实际上是在修改这个共享的子数组元素,所以原数组linsys也会跟着变化。

解决方法

要实现真正的独立副本,需要对二维数组进行深拷贝,确保每个子数组也被复制。有几种常用方式:

方法1:使用map + slice()复制每一行

把原代码里的const input = linsys.slice()替换成:

const input = linsys.map(row => row.slice())

map遍历原数组的每一行,对每一行调用slice()生成该行的副本,这样input的所有子数组都是独立的,修改时不会影响原数组。

方法2:使用JSON序列化(适合纯数值数组)

如果数组里只有数值类型,也可以用这种简单方式:

const input = JSON.parse(JSON.stringify(linsys))

注意:这种方法不适合包含函数、Symbol等特殊类型的数组,但你的场景是纯数值二维数组,完全适用。

修改后的完整代码

class ChapterOne {
    
    // Gauss Jordan Elimination
    // Notes: Only solve system of linear equation with one solution
    static gaussJordanElim( linsys : number[][] ) {
        const numOfEquation = linsys.length
        const numOfUnknown = linsys[0].length - 1
        if (numOfUnknown > numOfEquation) return 'This System of Linear Equation either have no solution or have infinite solutions'
        
        // 深拷贝二维数组,确保子数组独立
        const input = linsys.map(row => row.slice())
        const length = input.length
        // pointer = i, row to operate = j, column to operate = k
        for (let i = 0; i < length; i += 1) {
            if (input[i][i] === 0) return 'Mathematical Error! Cannot divide by zero'
            for (let j = 0; j < length; j += 1) {
                if (i !== j) {
                    const ratio = input[j][i] / input[i][i]
                    for (let k = 0; k < length + 1; k += 1) {
                        input[j][k] = input[j][k] - ratio * input[i][k]
                    }
                }
            }
        }
        console.log(input)
        console.log(linsys)

        const output = input.map((row, pointer) => row[length] / row[pointer])
        return output
    }
}

内容的提问来源于stack exchange,提问作者Fritz Adelbertus Sitindaon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 05:25:16