如果我有
array1 := []int{1, 3, 4, 5}
array2 := []int{2, 4, 6, 8}
我想在array2[2]
6
之前插入array1[1]
即3
,以便array1
成为{1, 6, 3, 4, 5}
的切片。我该怎么办?
我在线阅读的大多数技术都涉及使用:
运算符,但也会导致插入剩余的元素。如何在切片中的索引处附加单个值?
答案 0 :(得分:15)
您需要一个简单的append
:
a = append(a[:index+1], a[index:]...)
a[index] = value
注意:len(a) > 0 && index < len(a)
应该{{1}},表示len(a) == index
或空片或在最后一个元素之后追加:
nil
插入a = append(a, value)
s的切片的索引零处:
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
}
对于OP:
a := []int{10, 30, 40}
a = insert(a, 1, 20)
fmt.Println(a) // [10 20 30 40]
基准:
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]
代码:
len(a)==32:
BenchmarkInsert-8 6286105 203 ns/op 512 B/op 1 allocs/op
BenchmarkInsert2-8 5619445 214 ns/op 512 B/op 1 allocs/op
len(a)==1_000:
BenchmarkInsert-8 235446 4541 ns/op 16384 B/op 1 allocs/op
BenchmarkInsert2-8 240547 5143 ns/op 16384 B/op 1 allocs/op
len(a)==1_000_000:
BenchmarkInsert-8 381 2687634 ns/op 16007171 B/op 1 allocs/op
BenchmarkInsert2-8 428 2845477 ns/op 10002434 B/op 1 allocs/op
您可以将两个第一步合并为一个;通过使用:
var a = make([]int, 32)
var r []int
func BenchmarkInsert(b *testing.B) {
for i := 0; i < b.N; i++ {
r = insert(a, 0, 1)
}
}
func BenchmarkInsert2(b *testing.B) {
for i := 0; i < b.N; i++ {
r = insert2(a, 0, 1)
}
}
func insert2(a []int, index int, value int) []int {
a = append(a, a[len(a)-1]) // Step 1
copy(a[index+1:], a[index:]) // Step 2
a[index] = value // Step 3
return 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:]...) // Step 1+2
a[index] = value // Step 3
return a
}
a = append(a[:index+1], a[index:]...)
根据基准,哪种方法更有效。
答案 1 :(得分:12)
简单,高效和合乎逻辑的方式:
array1
有足够的容量(长度)来容纳新的可插入元素。要做到这一点,请使用构建append()
附加单个元素(不管它是什么,它会被覆盖)。copy()
(之前想要插入的元素)。在代码中:
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)
输出(在Go Playground上尝试):
[1 6 3 4 5]
答案 2 :(得分: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)
}
答案 3 :(得分:1)
我发现问题设置非常棘手。
改写,他们想插入一个元素。在这里,我们有一个数组,其中缺少元素3
,我们想将其插入。
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 :(得分: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) {
// extend array by one
*array = append(*array, "")
// shift values
copy((*array)[position+1:], (*array)[position:])
// insert value
(*array)[position] = value
}
答案 5 :(得分: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:]...)...)
}
答案 6 :(得分:0)
我不知道它是否最佳,但是这段代码对我有用:
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
}
以您为例,只需致电
sliceins(array1, 1, array2[2])
答案 7 :(得分: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
希望对您有帮助