在给定的索引位置插入一个值到切片中。

huangapple go评论83阅读模式
英文:

Insert a value in a slice at a given index

问题

给定

array1 := []int{1, 3, 4, 5}
array2 := []int{2, 4, 6, 8}

我想要将 array2[2],即 6,插入到 array1[1],即在 3 之前,使得 array1 变成 {1, 6, 3, 4, 5}。我该如何做到这一点?

大多数我在网上阅读到的技巧都涉及使用 : 运算符,但结果会导致剩余的元素也被插入。我该如何在切片中的特定索引位置添加单个值?

英文:

Given

array1 := []int{1, 3, 4, 5}
array2 := []int{2, 4, 6, 8}

I want to insert array2[2] i.e 6 at array1[1] i.e before 3 so that array1 becomes a slice of {1, 6, 3, 4, 5}. How can I do it?

Most the techniques I read online involve using the : operator but results in remaining elements being inserted as well. How can I append single values at an index in a slice?

答案1

得分: 98

一个简单的append就是你需要的:

a = append(a[:index+1], a[index:]...)
a[index] = value

注意:len(a) > 0 && index < len(a)

如果len(a) == index,意味着nil或空切片或在最后一个元素之后追加:

a = append(a, value)

在索引为零的切片中插入int

a = append([]int{value}, a...)

全部放在一个函数中:

// 0 <= index <= len(a)
func insert(a []int, index int, value int) []int {
	if len(a) == index { // nil or empty slice or after last element
		return append(a, value)
	}
	a = append(a[:index+1], a[index:]...) // index < len(a)
	a[index] = value
	return a
}

用法:

a := []int{10, 30, 40}
a = insert(a, 1, 20)
fmt.Println(a) // [10 20 30 40]

对于 OP(原始问题):

slice1 := []int{1, 3, 4, 5}
slice2 := []int{2, 4, 6, 8}
// slice1 = insert(slice1, 1, slice2[2])
slice1 = append(slice1[:2], slice1[1:]...)
slice1[1] = slice2[2]

fmt.Println(slice1) // [1 6 3 4 5]

基准测试:

go version
# go version go1.16.3 linux/amd64
make bench
go test -benchmem -bench . -args -n 32
# BenchmarkInsert-8     4125085  275.0 ns/op  512 B/op  1 allocs/op
# BenchmarkInsert2-8    3778551  316.0 ns/op  512 B/op  1 allocs/op

go test -benchmem -bench . -args -n 1000
# BenchmarkInsert-8      198364  5876 ns/op  16384 B/op  1 allocs/op
# BenchmarkInsert2-8    205197  7123 ns/op  16384 B/op  1 allocs/op

go test -benchmem -bench . -args -n 1000000
# BenchmarkInsert-8         643  1898436 ns/op  10002437 B/op  1 allocs/op
# BenchmarkInsert2-8        368  3248385 ns/op  10002436 B/op  1 allocs/op

代码:

func insert(a []int, index int, value int) []int {
	a = append(a[:index+1], a[index:]...) // 步骤 1+2
	a[index] = value                      // 步骤 3
	return a
}
func insert2(a []int, index int, value int) []int {
	last := len(a) - 1
	a = append(a, a[last])           // 步骤 1
	copy(a[index+1:], a[index:last]) // 步骤 2
	a[index] = value                 // 步骤 3
	return a
}
func BenchmarkInsert(b *testing.B) {
	for i := 0; i < b.N; i++ {
		r = insert(a, 2, 42)
	}
}
func BenchmarkInsert2(b *testing.B) {
	for i := 0; i < b.N; i++ {
		r = insert2(a, 2, 42)
	}
}

var (
	n    = flag.Int("n", 32, "buffer length")
	a, r []int
)

// We use TestMain to set up the buffer.
func TestMain(m *testing.M) {
	flag.Parse()
	a = make([]int, *n)
	os.Exit(m.Run())
}

你可以将前两个步骤合并为一个步骤,使用:

a = append(a[:index+1], a[index:]...)
  1. 这确保数组有足够的容量来容纳新元素。
  2. 这将所有必需的元素复制到更高的一个索引位置,为新元素腾出空间。
  3. 使用单个赋值语句设置索引处的元素:a[index] = value

根据基准测试,这种方法更高效。


如果你需要在index > cap(a)处插入(注意:未经测试的代码)- 在 Go Playground 上尝试

package main

import "fmt"

func insert(a []int, index int, value int) []int {
	n := len(a)
	if index < 0 {
		index = (index%n + n) % n
	}
	switch {
	case index == n: // nil or empty slice or after last element
		return append(a, value)

	case index < n: // index < len(a)
		a = append(a[:index+1], a[index:]...)
		a[index] = value
		return a

	case index < cap(a): // index > len(a)
		a = a[:index+1]
		for i := n; i < index; i++ {
			a[i] = 0
		}
		a[index] = value
		return a

	default:
		b := make([]int, index+1) // malloc
		if n > 0 {
			copy(b, a)
		}
		b[index] = value
		return b
	}
}

func main() {
	a := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	a = a[:5]
	fmt.Println(insert(a, 7, 70)) // [0 1 2 3 4 0 0 70]

	a = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	a = a[:4]
	fmt.Println(insert(a, 5, 50)) // [0 1 2 3 0 50]

	fmt.Println(insert(make([]int, 0, 50), 10, 10)) // [0 0 0 0 0 0 0 0 0 0 10]

	fmt.Println(insert([]int{1}, -1, 10))       // [10 1]
	fmt.Println(insert([]int{1, 2, 3}, -2, 10)) // [1 10 2 3]
	fmt.Println(insert([]int{1, 2, 3}, -1, 10)) // [1 2 10 3]
	fmt.Println(insert([]int{1, 2, 3}, -4, 10)) // [1 2 10 3]

	fmt.Println(insert(nil, 0, 0))       // [0]
	fmt.Println(insert([]int{}, 0, 0))   // [0]
	fmt.Println(insert([]int{1}, 1, 10)) // [1 10]

	fmt.Println(insert(nil, 5, 50)) // [0 0 0 0 0 50]

	fmt.Println(insert(make([]int, 0, 1), 1, 10)) // [0 10]
	fmt.Println(insert(make([]int, 0, 1), 2, 20)) // [0 0 20]
	fmt.Println(insert(make([]int, 0, 1), 3, 30)) // [0 0 0 30]

	fmt.Println(insert([]int{0, 10, 20, 30}, 5, 50)) // [0 10 20 30 0 50]
	fmt.Println(insert([]int{0}, 5, 50))             // [0 0 0 0 0 50]
	fmt.Println(insert([]int{0, 10}, 0, 0))          // [0 0 10]
	fmt.Println(insert([]int{0, 10}, 1, 5))          // [0 5 10]
	fmt.Println(insert(make([]int, 5, 50), 0, 0))    // [0 0 0 0 0 0]
}

使用泛型(注意:未经测试的代码)- 在 Go Playground 上尝试

package main

import "fmt"

func insert[T any](a []T, index int, value T) []T {
	n := len(a)
	if index < 0 {
		index = (index%n + n) % n
	}
	switch {
	case index == n: // nil or empty slice or after last element
		return append(a, value)

	case index < n: // index < len(a)
		a = append(a[:index+1], a[index:]...)
		a[index] = value
		return a

	case index < cap(a): // index > len(a)
		a = a[:index+1]
		var zero T
		for i := n; i < index; i++ {
			a[i] = zero
		}
		a[index] = value
		return a

	default:
		b := make([]T, index+1) // malloc
		if n > 0 {
			copy(b, a)
		}
		b[index] = value
		return b
	}
}

func main() {
	a := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	a = a[:5]
	fmt.Println(insert(a, 7, 70)) // [0 1 2 3 4 0 0 70]

	a = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	a = a[:4]
	fmt.Println(insert(a, 5, 50)) // [0 1 2 3 0 50]

	fmt.Println(insert(make([]int, 0, 50), 10, 10)) // [0 0 0 0 0 0 0 0 0 0 10]

	fmt.Println(insert([]int{1}, -1, 10))       // [10 1]
	fmt.Println(insert([]int{1, 2, 3}, -2, 10)) // [1 10 2 3]
	fmt.Println(insert([]int{1, 2, 3}, -1, 10)) // [1 2 10 3]
	fmt.Println(insert([]int{1, 2, 3}, -4, 10)) // [1 2 10 3]

	fmt.Println(insert(nil, 0, 0))       // [0]
	fmt.Println(insert([]int{}, 0, 0))   // [0]
	fmt.Println(insert([]int{1}, 1, 10)) // [1 10]

	fmt.Println(insert(nil, 5, 50)) // [0 0 0 0 0 50]

	fmt.Println(insert(make([]int, 0, 1), 1, 10)) // [0 10]
	fmt.Println(insert(make([]int, 0, 1), 2, 20)) // [0 0 20]
	fmt.Println(insert(make([]int, 0, 1), 3, 30)) // [0 0 0 30]

	fmt.Println(insert([]int{0, 10, 20, 30}, 5, 50)) // [0 10 20 30 0 50]
	fmt.Println(insert([]int{0}, 5, 50))             // [0 0 0 0 0 50]
	fmt.Println(insert([]int{0, 10}, 0, 0))          // [0 0 10]
	fmt.Println(insert([]int{0, 10}, 1, 5))          // [0 5 10]
	fmt.Println(insert(make([]int, 5, 50), 0, 0))    // [0 0 0 0 0 0]
}
英文:

A simple append is what you need:

a = append(a[:index+1], a[index:]...)
a[index] = value

Note: len(a) &gt; 0 &amp;&amp; index &lt; len(a)

Should len(a) == index, meaning nil or empty slice or append after the last element:

a = append(a, value)

Inserting at the index zero for slice of ints:

a = append([]int{value}, a...)

All in one function:

// 0 &lt;= index &lt;= len(a)
func insert(a []int, index int, value int) []int {
if len(a) == index { // nil or empty slice or after last element
return append(a, value)
}
a = append(a[:index+1], a[index:]...) // index &lt; len(a)
a[index] = value
return a
}

Usage:

	a := []int{10, 30, 40}
a = insert(a, 1, 20)
fmt.Println(a) // [10 20 30 40]

And for the OP:

	slice1 := []int{1, 3, 4, 5}
slice2 := []int{2, 4, 6, 8}
// slice1 = insert(slice1, 1, slice2[2])
slice1 = append(slice1[:2], slice1[1:]...)
slice1[1] = slice2[2]
fmt.Println(slice1) // [1 6 3 4 5]

Benchmark:

go version
# go version go1.16.3 linux/amd64
make bench
go test -benchmem -bench . -args -n 32
# BenchmarkInsert-8    	 4125085  275.0 ns/op  512 B/op  1 allocs/op
# BenchmarkInsert2-8   	 3778551  316.0 ns/op  512 B/op  1 allocs/op
go test -benchmem -bench . -args -n 1000
# BenchmarkInsert-8    	  198364  5876 ns/op  16384 B/op  1 allocs/op
# BenchmarkInsert2-8   	  205197  7123 ns/op  16384 B/op  1 allocs/op
go test -benchmem -bench . -args -n 1000000
# BenchmarkInsert-8    	     643  1898436 ns/op	10002437 B/op  1 allocs/op
# BenchmarkInsert2-8   	     368  3248385 ns/op	10002436 B/op  1 allocs/op

Code:

func insert(a []int, index int, value int) []int {
a = append(a[:index+1], a[index:]...) // Step 1+2
a[index] = value                      // Step 3
return a
}
func insert2(a []int, index int, value int) []int {
last := len(a) - 1
a = append(a, a[last])           // Step 1
copy(a[index+1:], a[index:last]) // Step 2
a[index] = value                 // Step 3
return a
}
func BenchmarkInsert(b *testing.B) {
for i := 0; i &lt; b.N; i++ {
r = insert(a, 2, 42)
}
}
func BenchmarkInsert2(b *testing.B) {
for i := 0; i &lt; b.N; i++ {
r = insert2(a, 2, 42)
}
}
var (
n    = flag.Int(&quot;n&quot;, 32, &quot;buffer length&quot;)
a, r []int
)
// We use TestMain to set up the buffer.
func TestMain(m *testing.M) {
flag.Parse()
a = make([]int, *n)
os.Exit(m.Run())
}

You may combine the two first steps to one; by using:

	a = append(a[:index+1], a[index:]...)
  1. This makes sure the array has enough capacity to accommodate the new element.
  2. This copies all required elements to one index higher to make room for the new element.
  3. Set the element at the index, using a single assignment: a[index] = value

Which is more efficient, according to the benchmarks.


Should you need to insert at index &gt; cap(a) (note: untested code) - try it on the The Go Playground:

package main
import &quot;fmt&quot;
func insert(a []int, index int, value int) []int {
n := len(a)
if index &lt; 0 {
index = (index%n + n) % n
}
switch {
case index == n: // nil or empty slice or after last element
return append(a, value)
case index &lt; n: // index &lt; len(a)
a = append(a[:index+1], a[index:]...)
a[index] = value
return a
case index &lt; cap(a): // index &gt; len(a)
a = a[:index+1]
for i := n; i &lt; index; i++ {
a[i] = 0
}
a[index] = value
return a
default:
b := make([]int, index+1) // malloc
if n &gt; 0 {
copy(b, a)
}
b[index] = value
return b
}
}
func main() {
a := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
a = a[:5]
fmt.Println(insert(a, 7, 70)) // [0 1 2 3 4 0 0 70]
a = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
a = a[:4]
fmt.Println(insert(a, 5, 50)) // [0 1 2 3 0 50]
fmt.Println(insert(make([]int, 0, 50), 10, 10)) // [0 0 0 0 0 0 0 0 0 0 10]
fmt.Println(insert([]int{1}, -1, 10))       // [10 1]
fmt.Println(insert([]int{1, 2, 3}, -2, 10)) // [1 10 2 3]
fmt.Println(insert([]int{1, 2, 3}, -1, 10)) // [1 2 10 3]
fmt.Println(insert([]int{1, 2, 3}, -4, 10)) // [1 2 10 3]
fmt.Println(insert(nil, 0, 0))       // [0]
fmt.Println(insert([]int{}, 0, 0))   // [0]
fmt.Println(insert([]int{1}, 1, 10)) // [1 10]
fmt.Println(insert(nil, 5, 50)) // [0 0 0 0 0 50]
fmt.Println(insert(make([]int, 0, 1), 1, 10)) // [0 10]
fmt.Println(insert(make([]int, 0, 1), 2, 20)) // [0 0 20]
fmt.Println(insert(make([]int, 0, 1), 3, 30)) // [0 0 0 30]
fmt.Println(insert([]int{0, 10, 20, 30}, 5, 50)) // [0 10 20 30 0 50]
fmt.Println(insert([]int{0}, 5, 50))             // [0 0 0 0 0 50]
fmt.Println(insert([]int{0, 10}, 0, 0))          // [0 0 10]
fmt.Println(insert([]int{0, 10}, 1, 5))          // [0 5 10]
fmt.Println(insert(make([]int, 5, 50), 0, 0))    // [0 0 0 0 0 0]
}

Using generics (note: untested code) - try it on the The Go Playground:

package main
import &quot;fmt&quot;
func insert[T any](a []T, index int, value T) []T {
n := len(a)
if index &lt; 0 {
index = (index%n + n) % n
}
switch {
case index == n: // nil or empty slice or after last element
return append(a, value)
case index &lt; n: // index &lt; len(a)
a = append(a[:index+1], a[index:]...)
a[index] = value
return a
case index &lt; cap(a): // index &gt; len(a)
a = a[:index+1]
var zero T
for i := n; i &lt; index; i++ {
a[i] = zero
}
a[index] = value
return a
default:
b := make([]T, index+1) // malloc
if n &gt; 0 {
copy(b, a)
}
b[index] = value
return b
}
}
func main() {
a := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
a = a[:5]
fmt.Println(insert(a, 7, 70)) // [0 1 2 3 4 0 0 70]
a = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
a = a[:4]
fmt.Println(insert(a, 5, 50)) // [0 1 2 3 0 50]
fmt.Println(insert(make([]int, 0, 50), 10, 10)) // [0 0 0 0 0 0 0 0 0 0 10]
fmt.Println(insert([]int{1}, -1, 10))       // [10 1]
fmt.Println(insert([]int{1, 2, 3}, -2, 10)) // [1 10 2 3]
fmt.Println(insert([]int{1, 2, 3}, -1, 10)) // [1 2 10 3]
fmt.Println(insert([]int{1, 2, 3}, -4, 10)) // [1 2 10 3]
fmt.Println(insert(nil, 0, 0))       // [0]
fmt.Println(insert([]int{}, 0, 0))   // [0]
fmt.Println(insert([]int{1}, 1, 10)) // [1 10]
fmt.Println(insert(nil, 5, 50)) // [0 0 0 0 0 50]
fmt.Println(insert(make([]int, 0, 1), 1, 10)) // [0 10]
fmt.Println(insert(make([]int, 0, 1), 2, 20)) // [0 0 20]
fmt.Println(insert(make([]int, 0, 1), 3, 30)) // [0 0 0 30]
fmt.Println(insert([]int{0, 10, 20, 30}, 5, 50)) // [0 10 20 30 0 50]
fmt.Println(insert([]int{0}, 5, 50))             // [0 0 0 0 0 50]
fmt.Println(insert([]int{0, 10}, 0, 0))          // [0 0 10]
fmt.Println(insert([]int{0, 10}, 1, 5))          // [0 5 10]
fmt.Println(insert(make([]int, 5, 50), 0, 0))    // [0 0 0 0 0 0]
}

答案2

得分: 46

简单、高效和逻辑清晰的方法:

  1. 确保array1有足够的容量(长度)来容纳新的可插入元素。为此,使用内置的append()方法追加一个元素(不管是什么,它将被覆盖)。
  2. 要插入一个元素,现有的元素必须被“移动”(复制到较高的索引位置),为该元素腾出空间,例如使用内置的copy()方法(要插入的元素之前的元素)。
  3. 使用单个赋值将元素设置到正确的索引位置。

代码示例:

array1 := []int{1, 3, 4, 5}
array2 := []int{2, 4, 6, 8}
array1 = append(array1, 0)   // 步骤1
copy(array1[2:], array1[1:]) // 步骤2
array1[1] = array2[2]        // 步骤3
fmt.Println(array1)

输出结果(在Go Playground上尝试):

[1 6 3 4 5]

特殊情况下的优化

请注意,在某些特殊情况下(当切片元素很大,比如一个大的结构体),追加最后一个元素可能更快,并且只需要复制少1个元素(因为追加的最后一个元素正好在它应该在的位置)。

代码示例:

last := len(array1) - 1
array1 = append(array1, array1[last]) // 步骤1
copy(array1[2:], array1[1:last])      // 步骤2
array1[1] = array2[2]                 // 步骤3

这将得到相同的切片。在Go Playground上尝试这个示例。

英文:

Simple, efficient and logical way:

  1. Make sure array1 has enough capacity (length) to accomodate the new, insertable element. To do that, append a single element using the builting append() (doesn't matter what that is, it'll get overwritten).
  2. To insert an element, existing elements must be shifted (copied over to 1 index higher) to make room for that element, e.g. using the builtin copy() (elements you want to insert before).
  3. Set the element at the proper index, using a single assignment.

In code:

array1 := []int{1, 3, 4, 5}
array2 := []int{2, 4, 6, 8}
array1 = append(array1, 0)   // Step 1
copy(array1[2:], array1[1:]) // Step 2
array1[1] = array2[2]        // Step 3
fmt.Println(array1)

Output (try it on the Go Playground):

[1 6 3 4 5]

Optimization in special cases

Note that in some special cases (when the slice element is big, like a big struct), it may be faster to append the last element, and then it's enough to copy 1 less elements (because the appended last element is right where it needs to be).

This is how it looks like:

last := len(array1) - 1
array1 = append(array1, array1[last]) // Step 1
copy(array1[2:], array1[1:last])      // Step 2
array1[1] = array2[2]                 // Step 3

This will result in the same slice. Try this one on the Go Playground.

答案3

得分: 11

我发现问题的设置相当棘手。

重新表述一下,他们想要插入一个元素。这里我们有一个数组,其中缺少元素3,我们想要插入它。

package main

import (
	"fmt"
)

func main() {
	a := []int{1, 2, 4, 5, 6}
	b := 3

    // 为新元素在数组中腾出空间。你可以给它赋任何值。
	a = append(a, 0)   
	fmt.Println(a)

    // 将从索引2开始的元素复制到从索引3开始的元素中。
	copy(a[3:], a[2:])  
	fmt.Println(a)
	
	a[2] = b         
	fmt.Println(a)
}
英文:

I found the question setup pretty tricky to follow.

Rephrased, they want to insert an element. Here we have an array where it's missing the element 3 and we want to insert it.

package main
import (
&quot;fmt&quot;
)
func main() {
a := []int{1, 2, 4, 5, 6}
b := 3
// Make space in the array for a new element. You can assign it any value.
a = append(a, 0)   
fmt.Println(a)
// Copy over elements sourced from index 2, into elements starting at index 3.
copy(a[3:], a[2:])  
fmt.Println(a)
a[2] = b         
fmt.Println(a)
}

答案4

得分: 3

扩展@Volker的答案,我在这里也放置了答案https://play.golang.org/p/3Hla2y2ava,如果你想测试的话。

package main

import "fmt"

func main() {
    array1 := []int{1, 3, 4, 5}
    array2 := []int{2, 4, 6, 8}
    temp := append([]int{array2[2]}, array1[1:]...)
    array1 = append(array1[:1], temp...)
    fmt.Println(array1)
}
英文:

extending the answer from @Volker, i put the answer here https://play.golang.org/p/3Hla2y2ava too if you want to test it.

package main
import &quot;fmt&quot;
func main() {
array1 := []int{1, 3, 4, 5}
array2 := []int{2, 4, 6, 8}
temp := append([]int{array2[2]}, array1[1:]...)
array1 = append(array1[:1], temp...)
fmt.Println(array1)
}

答案5

得分: 1

根据icza的帖子,我编写了一个函数来移动切片/数组,我想与您分享:

package main

import "fmt"

func main() {
    s := []string{"a", "c", "d"}
    shiftArray(&s, 1, "b")
    fmt.Println(s)
}

func shiftArray(array *[]string, position int, value string) {
    // 扩展数组长度
    *array = append(*array, "")

    // 移动数值
    copy((*array)[position+1:], (*array)[position:])

    // 插入值
    (*array)[position] = value
}
英文:

Based on icza's post i wrote a function to shift the slice / array which I want to share with you:

package main
import &quot;fmt&quot;
func main() {
s := []string{&quot;a&quot;, &quot;c&quot;, &quot;d&quot;}
shiftArray(&amp;s, 1, &quot;b&quot;)
fmt.Println(s)
}
func shiftArray(array *[]string, position int, value string) {
//  extend array by one
*array = append(*array, &quot;&quot;)
// shift values
copy((*array)[position+1:], (*array)[position:])
// insert value
(*array)[position] = value
}

答案6

得分: 1

以下解决方案对我有效:

func insert(a []int, c int, i int) []int {
    return append(a[:i], append([]int{c}, a[i:]...)...)
}

你可以通过空接口使其更通用:

func insert(a []interface{}, c interface{}, i int) []interface{} {
    return append(a[:i], append([]interface{}{c}, a[i:]...)...)
}
英文:

The following solution worked for me

func insert(a []int, c int, i int) []int {
return append(a[:i], append([]int{c}, a[i:]...)...)
}

You can make it more general via empty interfaces

func insert(a []interface{}, c interface{}, i int) []interface{} {
return append(a[:i], append([]interface{}{c}, a[i:]...)...)
}

答案7

得分: 1

这是一个一行代码:

append(array1[:1], append(array2[2:3], array1[1:]...)...)

Go Playground

英文:

Here a one-liner:

append(array1[:1], append(array2[2:3], array1[1:]...)...)

Go Playground

答案8

得分: 1

大多数答案都是旧的,有一个官方的slices.Insert函数。

文档

它的头部是:

func Insert[S ~[]E, E any](s S, i int, v ...E) S

你的用例:

package main

import (
	"fmt";

	"golang.org/x/exp/slices"
)

func main() {
	array1 := []int{1, 3, 4, 5}
	array2 := []int{2, 4, 6, 8}

	array1 = slices.Insert(array1, 1, array2[2])
	fmt.Println(array1) // 输出:[1 6 3 4 5]
}

请注意,它返回新的切片,而不是直接修改输入参数。

另外,golang.org/x/exp包被称为实验性包,这意味着这些函数在将来可能会被更改或删除。

你可以在这里看到它的实现方式。它还考虑了切片的cap,如果新的len超过了当前的cap,会进行适当的移动。

英文:

Most of the answers are old and there is a official slices.Insert function.

Docs

Its header is:

func Insert[S ~[]E, E any](s S, i int, v ...E) S

Your use case:

package main

import (
	&quot;fmt&quot;

	&quot;golang.org/x/exp/slices&quot;
)

func main() {
	array1 := []int{1, 3, 4, 5}
	array2 := []int{2, 4, 6, 8}

	array1 = slices.Insert(array1, 1, array2[2])
	fmt.Println(array1) // prints: [1 6 3 4 5]
}

Note that it returns the new slice, not modifies the input parameter in-place.

Also the package golang.org/x/exp known as experimental, means those functions can be changed in future or removed.

You can see how it is implemented here. It also takes cap of slice into considiration and makes appropriate move if the new len exceeds the current cap.

答案9

得分: 0

我不知道这段代码是否最优,但是这段代码对我来说是有效的:

func sliceins(arr []int, pos int, elem int) []int { //在切片的pos位置之前插入元素。如果pos >= len(arr),则插入到末尾
    if pos < 0 {
        pos = 0
    } else if pos >= len(arr) {
        pos = len(arr)
    }
    out := make([]int, len(arr)+1)
    copy(out[:pos], arr[:pos])
    out[pos] = elem
    copy(out[pos+1:], arr[pos:])
    return out
}

在你的情况下,只需调用:

sliceins(array1, 1, array2[2])
英文:

I don't know is it optimal or not, but this piece of code works for me:

func sliceins(arr []int, pos int, elem int) []int { //insert element before pos in slice. if pos &gt;= len(arr) insert into tail
if pos &lt; 0 {
pos = 0
} else if pos &gt;= len(arr) {
pos = len(arr)
}
out := make([]int, len(arr)+1)
copy(out[:pos], arr[:pos])
out[pos] = elem
copy(out[pos+1:], arr[pos:])
return out
}

In Your case just call

sliceins(array1, 1, array2[2])

答案10

得分: 0

我在另一个线程中回答了一个类似的问题。无论如何,我使用以下方法来操作切片和索引:

func insertInt(array []int, value int, index int) []int {
    return append(array[:index], append([]int{value}, array[index:]...)...)
}

func removeInt(array []int, index int) []int {
    return append(array[:index], array[index+1:]...)
}

func moveInt(array []int, srcIndex int, dstIndex int) []int {
    value := array[srcIndex]
    return insertInt(removeInt(array, srcIndex), value, dstIndex)
}

你可以在这里尝试运行它:

https://play.golang.org/p/Sfu1VsySieS

希望对你有帮助。

英文:

I answered a similar question in other thread. Anyway I used the following methods to play with slices and index:

func insertInt(array []int, value int, index int) []int {
return append(array[:index], append([]int{value}, array[index:]...)...)
}
func removeInt(array []int, index int) []int {
return append(array[:index], array[index+1:]...)
}
func moveInt(array []int, srcIndex int, dstIndex int) []int {
value := array[srcIndex]
return insertInt(removeInt(array, srcIndex), value, dstIndex)
}

You can play with it here:

https://play.golang.org/p/Sfu1VsySieS

I hope it'll help you

答案11

得分: 0

如何:

append(append(slice[:i], elem), slice[i:]...)
英文:

how about:

append(append(slice[:i], elem), slice[i:]...)

答案12

得分: 0

我发现很难理解a = append(a[:index+1], a[index:]...)这行代码。正如@lieblos所警告的那样,在原始切片上操作是棘手的。

这里有一个更简单的解决方案,尽管不够内存高效:

  var array3 []int
  array3 = append(array3, array1[:1]...)
  array3 = append(array3, array2[2])
  array3 = append(array3, array1[1:]...)
  array1 = array3

https://go.dev/play/p/rni5hgB0JNt

英文:

I found it's hard to wrap my head around a = append(a[:index+1], a[index:]...)
Also as @lieblos warned, working on the original slice is tricky.

Here is an easier solution, though not memory efficient:

  var array3 []int
array3 = append(array3, array1[:1]...)
array3 = append(array3, array2[2])
array3 = append(array3, array1[1:]...)
array1 = array3

https://go.dev/play/p/rni5hgB0JNt

huangapple
  • 本文由 发表于 2017年9月9日 14:56:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/46128016.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定