Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang multidimensional slice copy

I was trying to make a clone of multidimensional slice, because when I have changed elements in the duplicated slice, the elements in the original one were overwritten also.

The only method that worked for me was:

duplicate := make([][]int, len(matrix))
for i := 0; i < len(matrix); i++ {
    duplicate[i] = make([]int, len(matrix[0]))
    for j := 0; j < len(matrix[0]); j++ {
        duplicate[i][j] = matrix[i][j]
    }
}

is there any other way - shorter or more efficient to achieve the same result? thanks

like image 738
Serghei Luchianenco Avatar asked Aug 02 '17 15:08

Serghei Luchianenco


People also ask

How do you copy a slice in Golang?

Copying a slice using the append() function is really simple. You just need to define a new empty slice, and use the append() to add all elements of the src to the dst slice. In that way, you get a new slice with all the elements duplicated.

How do you make a 2D slice in go?

To create a 2D slice, we use append() to add each row. Then we can access the data by indexing through the slices. Slice example. Consider a slice of slices: we could use the term "jagged" to describe nested slices.

What is difference between array and slice in Golang?

Slices in Go and Golang The basic difference between a slice and an array is that a slice is a reference to a contiguous segment of an array. Unlike an array, which is a value-type, slice is a reference type. A slice can be a complete array or a part of an array, indicated by the start and end index.

How do you print a multidimensional array in Python?

To print out the entire two dimensional array we can use python for loop as shown below. We use end of line to print out the values in different rows.


1 Answers

You can use copy for the inner loop (which should be more efficient) and range for the outer loop (which results in nicer code).

Result:

duplicate := make([][]int, len(matrix))
for i := range matrix {
    duplicate[i] = make([]int, len(matrix[i]))
    copy(duplicate[i], matrix[i])
}

If your goal is efficiency, it may make sense to do more allocation up front. This doesn't lead to more readable code but will lead to more efficient code if you are doing this often. This code assumes you have at least one row and that all rows are of the same length. You will need to add tests for that.

n := len(matrix)
m := len(matrix[0])
duplicate := make([][]int, n)
data := make([]int, n*m)
for i := range matrix {
    start := i*m
    end := start + m
    duplicate[i] = data[start:end:end]
    copy(duplicate[i], matrix[i])
}

Depending on what you are doing, it may make sense to make a "matrix type" that is implemented using only a single slice. A slice of slices is not the most efficient data structure, even if it is simpler to work with.


Before deciding if you need to be efficient, make sure that you are spending a lot of time doing copying using profiling. Then, after you have determined this is in fact a hotspot, start running benchmarks. See https://golang.org/pkg/testing/#hdr-Benchmarks for details.

like image 186
Stephen Weinberg Avatar answered Sep 18 '22 22:09

Stephen Weinberg