如何在 Golang 中实现删除字符串数组的范围?

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

How to implement remove range on string array golang?

问题

你可以在Go中实现RemoveRange方法。以下是一个示例实现:

func removeRange(hashCode []string, idx int, count int) []string {
	if idx < 0 || idx >= len(hashCode) {
		return hashCode
	}

	end := idx + count
	if end > len(hashCode) {
		end = len(hashCode)
	}

	return append(hashCode[:idx], hashCode[end:]...)
}

这个方法接受一个字符串数组hashCode,一个起始索引idx和要删除的元素数量count作为参数。它会从hashCode数组中删除指定范围的元素,并返回修改后的新数组。

在方法中,我们首先检查起始索引idx是否有效。如果索引超出了数组范围,我们直接返回原始的hashCode数组。

然后,我们计算要删除的范围的结束索引end。如果结束索引超出了数组范围,我们将其设置为数组的长度。

最后,我们使用切片操作符[:idx][end:]将要删除的范围前后的元素连接起来,形成新的数组,并返回该数组作为结果。

你可以根据需要调用这个方法,传入合适的参数来删除指定范围的元素。

英文:

How can I implement RemoveRange method in golang? It is a method in C# as shown here

I want to implement RemoveRange method on my hashCode string array and return new modified array back if possible with those ranges remove.

func removeRange(hashCode []string, idx int, count int) []string {
	var temp []string
	for i, s := range hashCode {
			fmt.Println(i, s)
      // confuse here on what to do
	}

    return temp
}

答案1

得分: 3

简单地将切片切割到idx位置,跳过count个元素,并将剩余部分追加到第一个切片的结果中:

func removeRange(hashCode []string, idx int, count int) []string {
    return append(hashCode[:idx], hashCode[idx+count:]...)
}

测试代码:

s := []string{"0", "1", "2", "3", "4", "5"}
fmt.Println(s)
s = removeRange(s, 1, 2)
fmt.Println(s)

输出结果(在Go Playground上尝试):

[0 1 2 3 4 5]
[0 3 4 5]

**注意:**上述实现没有检查索引是否有效(是否在范围内)。如果不是,代码可能会引发错误。如果需要,添加必要的检查。

**注意#2:**上述实现修改了传递切片的元素,返回的切片将共享参数的支持数组。如果你想避免这种情况,如果你想保持输入不变并为结果分配一个新的切片,则可以这样做:

func removeRange(hashCode []string, idx int, count int) []string {
    result := make([]string, 0, len(hashCode)-count)
    result = append(result, hashCode[:idx]...)
    result = append(result, hashCode[idx+count:]...)
    return result
}

Go Playground上尝试这个版本。

英文:

Simply slice the slice up until idx, skip count elements and append the rest to the result of the first slicing:

func removeRange(hashCode []string, idx int, count int) []string {
	return append(hashCode[:idx], hashCode[idx+count:]...)
}

Testing it:

s := []string{&quot;0&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;}
fmt.Println(s)
s = removeRange(s, 1, 2)
fmt.Println(s)

Which outputs (try it on the Go Playground):

[0 1 2 3 4 5]
[0 3 4 5]

Note: the above implementation does not check whether indices are valid (whether they are in range). If not, the code could panic. Add necessary checks if you need to.

Note #2: the above implementation modifies the elements of the passed slice, the returned slice will share the backing array of the parameter. If you want to avoid this, if you want to leave the input intact and allocate a new slice for the result, then do so:

func removeRange(hashCode []string, idx int, count int) []string {
	result := make([]string, 0, len(hashCode)-count)
	result = append(result, hashCode[:idx]...)
	result = append(result, hashCode[idx+count:]...)
	return result
}

Try this one on the Go Playground.

答案2

得分: 1

在Go语言中,你根本不需要使用方法或函数来完成这个操作。Go的切片可以进行子切片和原地追加操作,这就是你可以快速简便地从任何切片中删除子集的方法。

假设你想要删除从索引2开始的2个元素,你只需要这样写:

Sub := append(original[:2], original[4:]...)

演示代码

这个方法的原理是:

  • original[:2] 创建一个子切片,从索引0开始,长度为2个元素(即索引0和1)。
  • append 函数用于将第一个子切片与剩余的切片(排除我们要跳过/删除的部分)合并。
  • original[4:] 创建另一个子切片,这次从索引4开始,直到 original 切片的末尾。就像在第一个子切片中没有明确指定0作为起始点一样,这里没有指定元素个数,Go语言会自动包含切片中剩余的所有元素。
  • ... 因为 append 是一个可变参数函数(内置函数,但你明白我的意思),我们需要将每个要追加的元素作为新的参数传递进去。... 运算符会展开子切片,并将每个元素作为单独的参数传递进去。

由于我们将新的切片赋值给了一个新变量 Sub,所以 original 切片保持不变。如果你想要覆盖原切片,只需将新切片赋值给同一个变量即可。


请注意,我是在手机上编写的,所以标记和代码可能不太准确,但至少这应该回答了你的问题。

英文:

You don't need a method or function for this at all in golang. Go slices can be subsliced and appended in place, which is how you can quickly and easily remove subsets from any slice.

Say you want to remove 2 elements, starting at index 2, you'd simply write:

Sub := append(original [:2], original [4:]...)

Demo

How this works:

  • original[:2] creates a sub-slice starting at 0, with a length of 2 elements (so index 0 and 1)
  • append because to this first part, we want to add the rest of the slice, minus the range we want to skip/remove
  • original[4:] creates another sub-slice, this time starting at index 4, and ending wherever original ends. Just like we don't explicitly mention 0 as the starting point in the first sub-slice, by not specifying a number of elements here, golang will just include all of the remaining elements in the slice.
  • ... because append is a variadic function (built-in, but you get the point), we need to pass in every element we want to append as a new argument. The ... operator expands the sub-slice and passes in every element as a separate argument.

Because we assigned the new slice to a new variable, original will remain unchanged, so if you want to overwrite the slice, you just assign it to the same variable.


Note I wrote this on my phone, so markup and code may not be quite right, but this should answer your question at least

答案3

得分: 1

我已经使用//注释来解释代码,如果没有注释,代码本身也很容易理解。

package main

import (
	"fmt"
	"os"
)

func RemoveRange(s []string, index, count int) []string {
	sLen := len(s)

	// 为了与C#实现的行为相似,具有相似的语义
	switch {
	case index < 0, count < 0: // 参数无效
		fmt.Fprintln(os.Stderr, "错误:参数超出范围")
		return s
	case index+count-1 >= sLen: // 范围超出限制
		fmt.Fprintln(os.Stderr, "错误:参数错误")
		return s
	}

	// 创建一个切片p,并预先分配所需的大小
	// 用于存储删除范围后的结果切片。
	// 结果 := s[:] -> s[:index] + s[index+count:]
	// 删除 := s[index:index+count-1]
	p := make([]string, 0, sLen-count)
	p = append(p, s[:index]...)
	p = append(p, s[index+count:]...)

	return p
}

func main() {
	s := []string{"0", "1", "2", "3", "4", "5"}
	fmt.Println(s)
	r := RemoveRange(s, 1, 3)
	fmt.Println(r)
}

输出:

[0 1 2 3 4 5]
[0 4 5]
英文:

I've explained the code using // comments and if not commented, code is self explanatory.

package main

import (
	&quot;fmt&quot;
	&quot;os&quot;
)

func RemoveRange(s []string, index, count int) []string {
	sLen := len(s)

	// Similar semantics to match (similar) the behavior of
	// C# implementation
	switch {
	case index &lt; 0, count &lt; 0: // arguments are not valid
		fmt.Fprintln(os.Stderr, &quot;error: argument out of range error&quot;)
		return s
	case index+count-1 &gt;= sLen: // range results in exceeding the limit
		fmt.Fprintln(os.Stderr, &quot;error: argument error&quot;)
		return s
	}

	// Create a slice p and pre-allocate the size required
	// to store the resultant slice after removing range.
	// Result := s[:] -&gt; s[:index] + s[index+count:]
	// Remove := s[index:index+count-1]
	p := make([]string, 0, sLen-count)
	p = append(p, s[:index]...)
	p = append(p, s[index+count:]...)

	return p
}

func main() {
	s := []string{&quot;0&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;}
	fmt.Println(s)
	r := RemoveRange(s, 1, 3)
	fmt.Println(r)
}

Output:

[0 1 2 3 4 5]
[0 4 5]

huangapple
  • 本文由 发表于 2022年1月31日 17:28:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/70923668.html
匿名

发表评论

匿名网友

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

确定