英文:
Moving an slice item from one position to another in go
问题
我正在尝试将一个项目从一个位置移动到另一个位置,这个项目是在一个切片中。以下是代码和输出结果:
indexToRemove := 1
indexWhereToInsert := 4
slice := []int{0,1,2,3,4,5,6,7,8,9}
slice = append(slice[:indexToRemove], slice[indexToRemove+1:]...)
fmt.Println("slice:", slice)
newSlice := append(slice[:indexWhereToInsert], 1)
fmt.Println("newSlice:", newSlice)
slice = append(newSlice, slice[indexWhereToInsert:]...)
fmt.Println("slice:", slice)
输出结果如下:
slice: [0 2 3 4 5 6 7 8 9]
newSlice: [0 2 3 4 1]
slice: [0 2 3 4 1 1 6 7 8 9]
但是我期望的输出应该是这样的:
slice: [0 2 3 4 5 6 7 8 9]
newSlice: [0 2 3 4 1]
slice: [0 2 3 4 1 **5** 6 7 8 9]
我的错误在哪里?
英文:
I' trying to move an item from one position to another inside a slice. Go Playground
indexToRemove := 1
indexWhereToInsert := 4
slice := []int{0,1,2,3,4,5,6,7,8,9}
slice = append(slice[:indexToRemove], slice[indexToRemove+1:]...)
fmt.Println("slice:", slice)
newSlice := append(slice[:indexWhereToInsert], 1)
fmt.Println("newSlice:", newSlice)
slice = append(newSlice, slice[indexWhereToInsert:]...)
fmt.Println("slice:", slice)
This produces to following output:
slice: [0 2 3 4 5 6 7 8 9]
newSlice: [0 2 3 4 1]
slice: [0 2 3 4 1 1 6 7 8 9]
But I would expect the output be like this:
slice: [0 2 3 4 5 6 7 8 9]
newSlice: [0 2 3 4 1]
slice: [0 2 3 4 1 **5** 6 7 8 9]
Where is my fault?
答案1
得分: 9
我之前遇到过同样的问题,我解决了如下:
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)
}
func main() {
slice := []int{0,1,2,3,4,5,6,7,8,9}
fmt.Println("slice: ", slice)
slice = insertInt(slice, 2, 5)
fmt.Println("slice: ", slice)
slice = removeInt(slice, 5)
fmt.Println("slice: ", slice)
slice = moveInt(slice, 1, 4)
fmt.Println("slice: ", slice)
}
你可以在这里查看代码:https://play.golang.org/p/Sfu1VsySieS
英文:
I had the same issue before and I solved as:
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)
}
func main() {
slice := []int{0,1,2,3,4,5,6,7,8,9}
fmt.Println("slice: ", slice)
slice = insertInt(slice, 2, 5)
fmt.Println("slice: ", slice)
slice = removeInt(slice, 5)
fmt.Println("slice: ", slice)
slice = moveInt(slice, 1, 4)
fmt.Println("slice: ", slice)
}
答案2
得分: 3
问题在于newSlice并不是slice的一个独立副本,它们引用同一个底层数组。
因此,当你对newSlice进行赋值时,你实际上修改的是底层数组,从而也修改了slice。
为了解决这个问题,你需要进行显式的复制:
package main
import (
"fmt"
)
func main() {
indexToRemove := 1
indexWhereToInsert := 4
slice := []int{0,1,2,3,4,5,6,7,8,9}
val := slice[indexToRemove]
slice = append(slice[:indexToRemove], slice[indexToRemove+1:]...)
fmt.Println("slice:", slice)
newSlice := make([]int, indexWhereToInsert+1)
copy(newSlice,slice[:indexWhereToInsert])
newSlice[indexWhereToInsert]=val
fmt.Println("newSlice:", newSlice)
fmt.Println("slice:", slice)
slice = append(newSlice, slice[indexWhereToInsert:]...)
fmt.Println("slice:", slice)
}
(请注意,我还添加了val变量,而不是将1硬编码为要插入的值。)
英文:
The problem is that newSlice is not a distinct copy of slice--they reference the same underlying array.
So when you assign to newSlice, you're modifying the underlying array, and thus slice, too.
To remedy this, you need to make an explicit copy:
package main
import (
"fmt"
)
func main() {
indexToRemove := 1
indexWhereToInsert := 4
slice := []int{0,1,2,3,4,5,6,7,8,9}
val := slice[indexToRemove]
slice = append(slice[:indexToRemove], slice[indexToRemove+1:]...)
fmt.Println("slice:", slice)
newSlice := make([]int, indexWhereToInsert+1)
copy(newSlice,slice[:indexWhereToInsert])
newSlice[indexWhereToInsert]=val
fmt.Println("newSlice:", newSlice)
fmt.Println("slice:", slice)
slice = append(newSlice, slice[indexWhereToInsert:]...)
fmt.Println("slice:", slice)
}
(Note that I've also added the val variable, rather than hardcoding 1 as the value to be inserted.)
答案3
得分: 1
这是一个简单的右移示例,没有使用复制,但包含一个循环来展示实际上都是指针。
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
for _, e := range s {
// 每次都会向右移动2个位置
fmt.Println(e, shiftRight(s, e))
}
}
func shiftRight(s []int, e int) []int {
if len(s) > 1 { // 如果只有一个元素,无法进行右移
// 遍历切片,找到要右移的元素
for i, item := range s {
if item == e {
if i == len(s)-1 {
break // 已经在末尾,无法再右移
}
s[i] = s[i+1]
s[i+1] = item
break
}
}
}
return s
}
英文:
Here's a simple shift right example without copy but also includes a loop showing how it's all really pointers.
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
for _, e := range s {
// Will always shift 2 as it's been shifted each time
fmt.Println(e, shiftRight(s, e))
}
}
func shiftRight(s []int, e int) []int {
if len(s) > 1 { // No where to shift to if 1 item
// Go through the slice finding the item to shift
for i, item := range s {
if item == e {
if i == len(s)-1 {
break // already at the end, can't shift any further
}
s[i] = s[i+1]
s[i+1] = item
break
}
}
}
return s
}
答案4
得分: 0
如果你需要带有泛型的omotto版本:
func insertInt[T any](array []T, value T, index int) []T {
return append(array[:index], append([]T{value}, array[index:]...)...)
}
func removeInt[T any](array []T, index int) []T {
return append(array[:index], array[index+1:]...)
}
func moveElement[T any](array []T, srcIndex int, dstIndex int) []T {
value := array[srcIndex]
return insertInt(removeInt(array, srcIndex), value, dstIndex)
}
英文:
If you need the omotto's version with generics:
func insertInt[T any](array []T, value T, index int) []T {
return append(array[:index], append([]T{value}, array[index:]...)...)
}
func removeInt[T any](array []T, index int) []T {
return append(array[:index], array[index+1:]...)
}
func moveElement[T any](array []T, srcIndex int, dstIndex int) []T {
value := array[srcIndex]
return insertInt(removeInt(array, srcIndex), value, dstIndex)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论