Concatenate 2 slices in golang
Asked Answered
H

3

9

I have 2 slices,

s1 := []int{1, 2, 3, 4, 5}
s2 := []int{3, 4, 5, 6, 7}

I want the resultant

s3 = []int{1, 2, 3, 4, 5, 3, 4, 5, 6, 7}

I am doing something like:

for _, x := range s1 {
        s2 = append(s2, x)
    }

This looks very trivial question but trust me I don't find a one line solution to this. How can we go about this?

Homology answered 19/9, 2017 at 16:47 Comment(1)
The Go 1.22 (Q1 2024) slices.Concat function should help.Marquesan
I
21

This is what the builtin append() function is for: to append values (which may be values of a slice) to the end of another. And the result is the concatenation.

If you want s3 to be "independent" of s1 and s2, then append s1 to an empty or nil slice, then append s2 to the result:

s3 := append(append([]int{}, s1...), s2...)
fmt.Println(s3)

If s3 may use / overlap s1, you can simply append s2 to s1:

s4 := append(s1, s2...)
fmt.Println(s4)

Output in both cases (try it on the Go Playground):

[1 2 3 4 5 3 4 5 6 7]

Note: What this "overlapping" means is that if you append values to s1, if it has enough capacity, no new slice will be allocated, s1 will be resliced to have enough length to accommodate the elements you want to append to it. This may have surprising side-effects if used unwisely, like in this example:

arr := [...]int{1, 2, 3, 4, 5, 6, 7, 0, 0, 0}

s1 := arr[:5]
s2 := arr[2:7]
fmt.Println("s1:", s1, "cap:", cap(s1))
fmt.Println("s2:", s2)

s3 := append(s1, s2...)
fmt.Println("s3:", s3)

fmt.Println("s2:", s2)

Output is (try it on the Go Playground):

s1: [1 2 3 4 5] cap: 10
s2: [3 4 5 6 7]
s3: [1 2 3 4 5 3 4 5 6 7]
s2: [3 4 5 3 4]

What may be surprising here is that when we appended s2 to s1 and stored the result in s3 (which is what we expected), contents (elements) of s2 also changed. The reason for this is that append() saw that s1 has enough capacity to append s2 to it (elements of s2), so it did not create a new array, it just resliced s1 and added elements "in-place". But the area where the additional elements were written is the exact same memory where elements of s2 reside, so elements of s2 also got overwritten.

Indoeuropean answered 19/9, 2017 at 16:51 Comment(0)
T
4

I would recommend you to give a look at this page: https://github.com/golang/go/wiki/SliceTricks

It's an official documentation by golang for slices. For your problem you just need to use append :)

Telophase answered 19/9, 2017 at 16:57 Comment(0)
S
1

Go 1.22

You can use slices.Concat from the standard library:

func main() {
    s1 := []int{1, 2, 3, 4, 5}
    s2 := []int{6, 7, 8, 9, 10}
    
    s := slices.Concat(s1, s2) 
    fmt.Println(s) // [1 2 3 4 5 6 7 8 9 10]
}

Playground: https://go.dev/play/p/mXKIoKO1J_b

In my personal opinion this looks nicer than append with the spread syntax .... Anyway, the actual implementation under the hood still uses just that, so you don't have to.

Surveyor answered 7/2 at 14:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.