英文:
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论