82

I have a slice which I created using

var x []int;
for i := 2; i < 10; i += 2 {
    x = append(x, i);
}

I want to prepend an integer to this slice, something like

x = append(2, x)

but obviously it won't work since append needs a slice as the first argument.

I have tried this but it only works for strings and it's not working in my case.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
coda
  • 2,188
  • 2
  • 22
  • 26

4 Answers4

177

Use a slice composite literal: []int{1}, For example:

package main

import (
    "fmt"
)

func main() {
    var x []int
    for i := 2; i < 10; i += 2 {
        x = append(x, i)
    }
    fmt.Println(x)

    x = append([]int{1}, x...)

    fmt.Println(x)
}

Playground: https://play.golang.org/p/Yc87gO7gJlD

Output:

[2 4 6 8]
[1 2 4 6 8]

However, this more efficient version may make fewer allocations, An allocation is only necessary when there is no spare slice capacity.

package main

import (
    "fmt"
)

func main() {
    var x []int
    for i := 2; i < 10; i += 2 {
        x = append(x, i)
    }
    fmt.Println(x)

    x = append(x, 0)
    copy(x[1:], x)
    x[0] = 1

    fmt.Println(x)
}

Playground: https://play.golang.org/p/fswXul_YfvD

Output:

[2 4 6 8]
[1 2 4 6 8]

Good code must be readable. In Go, we often hide implementaion details inside a function. Go compilers are optimizing compilers, small, simple functions (like prependInt) are inlined.

package main

import (
    "fmt"
)

func prependInt(x []int, y int) []int {
    x = append(x, 0)
    copy(x[1:], x)
    x[0] = y
    return x
}

func main() {
    var x []int
    for i := 2; i < 10; i += 2 {
        x = append(x, i)
    }
    fmt.Println(len(x), cap(x), x)

    x = prependInt(x, 1)

    fmt.Println(len(x), cap(x), x)
}

Playground: https://play.golang.org/p/wl6gvoXraKH

Output:

4 4 [2 4 6 8]
5 8 [1 2 4 6 8]

See Go SliceTricks.

Zombo
  • 1
  • 62
  • 391
  • 407
peterSO
  • 158,998
  • 31
  • 281
  • 276
  • Any type of slice can be prepended using this. You have to use zero value for the first `append()` of the `prependInt` function. Eg for string - `append(x, "")`. Zero values for various types can are briefly described [here](https://go.dev/tour/basics/12) – Mirza Prangon Sep 13 '22 at 14:34
  • These tricks are good if you only need to prepend an item or two. But if you're prepending in a loop, it is significantly better to reverse the array, **append** what you need, and then reverse the array again – Born2Smile Jul 30 '23 at 20:56
9

The current version is go1.14.11

Prepend without a for loop:

package main

import "fmt"
func main () {
  data := []int{1, 2, 3, 4}
  fmt.Println(data)
  data = append([]int{99}, data...)
  fmt.Println(data)
}

Example taken form: https://codingair.wordpress.com/2014/07/18/go-appendprepend-item-into-slice/

Works with integers: https://play.golang.org/p/gaLhB5_d1Iu

sanchezcl
  • 1,210
  • 11
  • 6
  • does this allocate ? or is there some trick in the compiler to improve it ? –  Apr 27 '21 at 15:13
  • The prepend operation shown here is identical to the accepted answer. The difference between this answer and the accepted answer is that the example data is created with a composite literal instead of a for loop. –  Apr 27 '21 at 16:26
  • 2
    @mh-cbon Yes, this allocates. See `prependInt` in PeterSo's answer for a solution that minimizes allocations. –  Apr 29 '21 at 03:03
-1

Another answer uses append and copy, but you can do it with just append, in one or two lines:

package main
import "fmt"

func main() {
   {
      a := []int{20, 30}
      a = append(append(a, 10), a...)[len(a):]
      fmt.Println(a)
   }
   {
      a := []int{20, 30}
      a = append(make([]int, 1), a...)
      a[0] = 10
      fmt.Println(a)
   }
   { // if starting with empty slice, use: a := make([]int, 0, 1)
      a := []int{20, 30}
      a = append(a[:1], a...)
      a[0] = 10
      fmt.Println(a)
   }
}

Or as another option, you can use linked list:

package main

import (
   "container/list"
   "fmt"
)

func main() {
   a := list.New()
   a.PushBack(20)
   a.PushBack(30)
   a.PushFront(10)
   for n := a.Front(); n != nil; n = n.Next() {
      fmt.Println(n.Value)
   }
}

https://golang.org/pkg/container/list

Zombo
  • 1
  • 62
  • 391
  • 407
  • `a = append([]int{10}, a...)` is simpler than the append options shown here. –  Apr 27 '21 at 16:03
-1

I know the Question is only for int but thought I'd add this to the discussion:

https://play.golang.com/p/PNax2a1rL3q

import (
    "golang.org/x/exp/constraints"
)

type Number interface {
    constraints.Signed | constraints.Unsigned | constraints.Float
}

func prepend[T Number](list []T, elems ...T) []T {
    results := make([]T, len(list)+len(elems))
    results = append(results, 0)
    copy(results[len(elems):], list)
    copy(results[:len(elems)], elems)
    return results
}

References:

stephanve
  • 94
  • 5
  • I downvoted because this seems overly complicated compared to `append(elems, list...)`. It’s also a lot slower (~2.5x to 3x slower on large slices), and the `append(results, 0)` in the middle adds a superfluous `0` in the result. – bfontaine Nov 15 '22 at 16:03