Home > database >  Changing an element in a multidimensional array doesen't work in Ruby
Changing an element in a multidimensional array doesen't work in Ruby

Time:11-19

I made a class that represents a matrix using a multidimensional array. The initialize method goes through every position and sets the value of the elements to the one specified, and the to_s method does the same but it just concatenates every element to a string. I'm writing an insert method that changes the value of the element of a given position to a given value, but it changes a whole value instead of just an element.

class Matrix
    attr_accessor :rows, :cols, :arr

    # Goes through the matrix setting everything with the "n" value
    def initialize(r, c, n = "a")
        @rows = r
        @cols = c
        @arr = Array.new(@rows)
        tmpArray = Array.new(@cols)

        i = 0

        while i < @rows
            j = 0
            while j < @cols
                tmpArray[j] = n
                j  = 1
            end

            @arr[i] = tmpArray
            i  = 1
        end

        return @arr
    end

    def to_s
        i = 0
        str = String.new

        while i < @rows
            j = 0
            str  << "("

            while j < @cols
                str << " "
                if @arr[i][j].is_a?String
                    str << @arr[i][j]
                else
                    str << @arr[i][j].to_s
                end

                j  = 1
            end

            str << " )\n"
            i  = 1
        end

        return str
    end

    # Calls and prints to_s
    def write
        print self.to_s

        return self.to_s
    end

    # Rewrites the element (r, c) as the value in "n"
    def insert(r, c, n)
        @arr[r][c] = n

        self.write
        return self
    end
end

The thing is that, when I print the matrix I notice that I didn't change just an element, but a whole column of the matrix.

a = Matrix.new(2, 2, 0)
a.insert(0, 0, 1)

a.write

# Expected output: ( 1 0 )
#                  ( 0 0 )

# Real output:     ( 1 0 )
#                  ( 1 0 )

The to_s method isn't failing. I already made a trace of it and tested it. I'm printing the real values that are in the positions of the matrix.

CodePudding user response:

Your program calls Array.new only twice, and it doesn't create arrays using any other methods, and it doesn't use dup or clone to copy any arrays. Therefore, you only have two different array objects in your program. Each element of @arr actually points to the same row array.

One idea for a solution would be to replace this line:

@arr[i] = tmpArray

with this:

@arr[i] = tmpArray.dup

However, your code is pretty long and I have not tried running it, so I do not know if that would be a complete solution.

  • Related