英文:
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:]...)
- 这确保数组有足够的容量来容纳新元素。
- 这将所有必需的元素复制到更高的一个索引位置,为新元素腾出空间。
- 使用单个赋值语句设置索引处的元素:
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) > 0 && index < 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 int
s:
a = append([]int{value}, a...)
All in one function:
// 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
}
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 < 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())
}
You may combine the two first steps to one; by using:
a = append(a[:index+1], a[index:]...)
- This makes sure the array has enough capacity to accommodate the new element.
- This copies all required elements to one index higher to make room for the new element.
- 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 > cap(a)
(note: untested code) - try it on the The 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]
}
Using generics (note: untested code) - try it on the The 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]
}
答案2
得分: 46
简单、高效和逻辑清晰的方法:
- 确保
array1
有足够的容量(长度)来容纳新的可插入元素。为此,使用内置的append()
方法追加一个元素(不管是什么,它将被覆盖)。 - 要插入一个元素,现有的元素必须被“移动”(复制到较高的索引位置),为该元素腾出空间,例如使用内置的
copy()
方法(要插入的元素之前的元素)。 - 使用单个赋值将元素设置到正确的索引位置。
代码示例:
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:
- Make sure
array1
has enough capacity (length) to accomodate the new, insertable element. To do that, append a single element using the builtingappend()
(doesn't matter what that is, it'll get overwritten). - 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). - 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 (
"fmt"
)
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 "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)
}
答案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 "fmt"
func main() {
s := []string{"a", "c", "d"}
shiftArray(&s, 1, "b")
fmt.Println(s)
}
func shiftArray(array *[]string, position int, value string) {
// extend array by one
*array = append(*array, "")
// 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:]...)...)
答案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.
Its header is:
func Insert[S ~[]E, E any](s S, i int, v ...E) S
Your use case:
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) // 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 >= len(arr) insert into tail
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
}
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论