如何将 Golang 中切片中的一个值移动到最后一个位置?

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

How to move a value in a slice to the last position in Golang?

问题

我想知道如何在Golang中将切片元素正确地移动到切片的最后一个位置。

例如:

func main() {
	slc := []int{1,2,3,4,5}
	fmt.Println(shiftEnd(slc,2))
}

func shiftEnd(s []int, x int) []int {
	return append(s[x:],s[:x]...)
}

这将得到 [3,4,5,1,2],我想知道如何得到 [1,3,4,5,2]
所以接收到的值将被移动到末尾,但其他值将保持原来的顺序。

Playground

英文:

I was wondering on how to properly move a slice element to the last position of a slice in Golang.

e.g:

func main() {
	slc := []int{1,2,3,4,5}
	fmt.Println(shiftEnd(slc,2))
}

func shiftEnd(s []int, x int) []int {
return append(s[x:],s[:x]...)
}

This will result in [3,4,5,1,2] I was wondering how to receive [1,3,4,5,2].
So the received value, will be moved to the end, but the others will be kept in the same order.

Playground

答案1

得分: 2

这是使用泛型的版本,可以处理任意类型的切片。

// 将 s[x] 处的元素移到切片末尾。
// 直接修改 `s`
func shiftEnd[T any](s []T, x int) []T {
	if x < 0 {
		return s
	}
	if x >= len(s)-1 {
		return s
	}
	tmp := s[x]
	// 由于新切片的容量适合,所以不需要分配内存
	s = append(s[:x], s[x+1:]...)
	// 追加到末尾
	// 由于新切片的容量适合,所以不需要分配内存
	s = append(s, tmp)
	return s
}

示例:https://go.dev/play/p/J7TmafgNwm3

func main() {
	test := []int{1, 2, 3, 4, 5, 6}
	fmt.Printf("before: %#v\n", test)
	out := shiftEnd(test, 2)
	fmt.Printf("after: %#v\nresult:  %#v\n", test, out)
}

输出:

before: []int{1, 2, 3, 4, 5, 6}
after:  []int{1, 2, 4, 5, 6, 3}
result: []int{1, 2, 4, 5, 6, 3}
英文:

Here you are, the versoin with generics. Can handle the slice of any type.

// Relocates element at s[x] to the end ov the slice.
// Modifies `s` in place
func shiftEnd[T any](s []T, x int) []T {
	if x &lt; 0 {
		return s
	}
	if x &gt;= len(s)-1 {
		return s
	}
	tmp := s[x]
	// No allocation since the new slice fits capacity
	s = append(s[:x], s[x+1:]...)
	// append to the end
	// no allocation, the new slice fits the capacity
	s = append(s, tmp)
	return s
}

Example: https://go.dev/play/p/J7TmafgNwm3

func main() {
	test := []int{1, 2, 3, 4, 5, 6}
	fmt.Printf(&quot;before: %#v\n&quot;, test)
	out := shiftEnd(test, 2)
	fmt.Printf(&quot;after: %#v\nresult:  %#v\n&quot;, test, out)
}

Output:

before: []int{1, 2, 3, 4, 5, 6}
after:  []int{1, 2, 4, 5, 6, 3}
result: []int{1, 2, 4, 5, 6, 3}

答案2

得分: 0

我正在为您翻译以下内容:

我正在使用这个代码片段解决方案进行尝试,似乎对我所寻找的功能有效。

func main() {
	s := []int{1, 2, 3, 4, 5}
	fmt.Println(shiftEnd(s, 2))
}

func shiftEnd(s []int, x int) []int {
	if len(s) < 1 {
		fmt.Println("No Enought Values")
		return s
	}

	if s[len(s)-1] == x {
		fmt.Println("Already in the end")
		return s
	}
	return append(append(s[:x-1], s[x:]...), x)
}

Playground

英文:

I was playing with this snippet solution, seems to work for what I was looking for.

func main() {
	s := []int{1, 2, 3, 4, 5}
	fmt.Println(shiftEnd(s, 2))

}

func shiftEnd(s []int, x int) []int {
	if len(s) &lt; 1 {
		fmt.Println(&quot;No Enought Values&quot;)
		return s
	}

	if s[len(s)-1] == x {
		fmt.Println(&quot;Already in the end&quot;)
		return s
	}
	return append(append(s[:x-1], s[x:]...), x)
}

Playground

答案3

得分: 0

请参考以下评论:

func shiftEnd(s []int, x int) []int {
    if len(s) <= 1 {
        return s
    }
    t := s[x]            // 保存要移动的值
    copy(s[x:], s[x+1:]) // 向下移动元素
    s[len(s)-1] = t      // 在末尾设置值
    return s
}

使用类型参数编写一个可以与任何切片类型一起使用的函数:

func shiftEnd[S ~[]E, E any](s S, x int) S {
    if len(s) <= 1 {
        return s
    }
    t := s[x]            // 保存要移动的值
    copy(s[x:], s[x+1:]) // 向下移动元素
    s[len(s)-1] = t      // 在末尾设置值
    return s
}

我对 OP 的问题有点困惑,因为 OP 的答案中将 x 既用作元素值又用作元素索引。本答案假设 OP 只打算将 x 用作索引。

英文:

See commentary for details:

func shiftEnd(s []int, x int) []int {
	if len(s) &lt;= 1 {
		return s
	}
	t := s[x]            // save value to move
	copy(s[x:], s[x+1:]) // shift elements down
	s[len(s)-1] = t      // set value at end
	return s
}

Use type parameters to write a function that works with any slice type:

func shiftEnd[S ~[]E, E any](s S, x int) S {
	if len(s) &lt;= 1 {
		return s
	}
	t := s[x]            // save value to move
	copy(s[x:], s[x+1:]) // shift elements down
	s[len(s)-1] = t      // set value at end
	return s
}

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

I am little confused about what OP is asking because OP's answer uses x as both an element value and an element index. This answer assumes that OP intended to use x as an index only.

huangapple
  • 本文由 发表于 2022年10月21日 12:43:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/74148841.html
匿名

发表评论

匿名网友

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

确定