Home > database >  My .slice() method mutate the original array (TypeScript)
My .slice() method mutate the original array (TypeScript)

Time:11-21

This is my first time writing a slice() method in TypeScript. I know that the slice() method should've return a copy of an array. Here is a bit snippet of the code

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
    }
}

In short I made a copy of the original array, did alot of manipulation to the copied array, and didn't want to mutate the original array but when I console.log both the copied and original, the original also change. Is there any clear explanation for this?

The main goal is to copy the original array, change the copied one, and maintain the original one.

CodePudding user response:

This is because .slice does a shallow copy and does not copy nested objects. Since you are using two dimensional array, this is expected.

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

Shallow cloning does not copy nested objects. So if an object contains an object, your .slice will keep a reference to the original copy of that object rather than creating a copy. Hence, the value changes.

In case of a shallow copy-

  • Objects will reflect change in the original place from where they were shallowly copied because they are stored as references (to their address in the Heap).
  • Primitive data types will NOT reflect change in the original place because they are directly stored in the callstack (in Execution Contexts).

For example:

var a = [
    [1, 2],    // This still is referencing to the original reference 
    [5,7]
]
  • Related