英文:
How to remove element of struct array in loop in golang
问题
问题
我有一个结构体数组:
type Config struct {
Applications []Application
}
注意:Config是用于json.Decode的结构体。
config = new(Config)
_ = decoder.Decode(&config)
在循环中,我有一些条件和通过键删除元素的操作。
for i, application := range config.Applications {
if i == 1 {
config.Applications = _removeApplication(i, config.Applications)
}
}
func _removeApplication(i int, list []Application) []Application {
if i < len(list)-1 {
list = append(list[:i], list[i+1:]...)
} else {
log.Print(list[i].Name)
list = list[:i]
}
return list
}
但是我总是遇到"out of range"错误。从结构体数组中删除元素的最佳方法是什么?
英文:
Problem
I have array of structs:
type Config struct {
Applications []Application
}
Note: Config - is a struct for json.Decode.
config = new(Config)
_ = decoder.Decode(&config)
In loop I have some condition and element deletion by key.
for i, application := range config.Applications {
if i == 1 {
config.Applications = _removeApplication(i, config.Applications)
}
}
func _removeApplication(i int, list []Application) []Application {
if i < len(list)-1 {
list = append(list[:i], list[i+1:]...)
} else {
log.Print(list[i].Name)
list = list[:i]
}
return list
}
But always I have "out of range" error. What is the best way to delete element by key from array of structs?
答案1
得分: 47
从Slice Tricks页面引用删除索引为i
的元素的代码段:
a = append(a[:i], a[i+1:]...)
// 或者
a = a[:i+copy(a[i:], a[i+1:])]
请注意,如果您计划从当前正在循环遍历的切片中删除元素,可能会引起问题。如果您删除的元素是当前元素(或已经循环遍历过的先前元素),那么在删除后,所有后续元素都会被移动,但range
循环不知道这一点,仍然会增加索引,导致跳过一个元素。
您可以通过使用向下循环来避免这个问题:
for i := len(config.Applications) - 1; i >= 0; i-- {
application := config.Applications[i]
// 判断是否需要删除当前元素的条件:
if haveToDelete {
config.Applications = append(config.Applications[:i],
config.Applications[i+1:]...)
}
}
英文:
Quoting from the Slice Tricks page deleting the element at index i
:
a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]
Note that if you plan to delete elements from the slice you're currently looping over, that may cause problems. And it does if the element you remove is the current one (or a previous element already looped over) because after the deletion all subsequent elements are shifted, but the range
loop does not know about this and will still increment the index and you skip one element.
You can avoid this by using a downward loop:
for i := len(config.Applications) - 1; i >= 0; i-- {
application := config.Applications[i]
// Condition to decide if current element has to be deleted:
if haveToDelete {
config.Applications = append(config.Applications[:i],
config.Applications[i+1:]...)
}
}
答案2
得分: 7
你之所以遇到这个错误,是因为你在一个初始长度为X的切片上进行循环,但在循环过程中删除了一些元素,导致切片的长度变为X-n。
如果你想从切片中删除特定索引处的元素,可以按照以下方式进行操作:
sliceA = append(sliceA[:indexOfElementToRemove], sliceA[indexOfElementToRemove+1:]...)
英文:
You are getting this error because you are doing a loop over a slice with an inital range of X length that became X-n because you remove some elements during loop.
If you want to delete an item at a specific index from a slice, you can do it this way:
sliceA = append(sliceA[:indexOfElementToRemove], sliceA[indexOfElementToRemove+1:]...)
答案3
得分: 4
这个问题有点旧,但我在StackOverflow上没有找到其他提到以下技巧的答案,这个技巧来自于Slice Tricks,用于过滤列表:
b := a[:0]
for _, x := range a {
if f(x) {
b = append(b, x)
}
}
所以在这种情况下,一个删除特定元素的函数可以像这样:
func removeApplications(apps []Applications) []Applications {
filteredApps := apps[:0]
for _, app := range apps {
if !removeApp {
filteredApps = append(filteredApps, app)
}
}
return filteredApps
}
英文:
This question is a bit older but I haven't found another answer on StackOverflow which mentions the following trick from the Slice Tricks to filter a list:
b := a[:0]
for _, x := range a {
if f(x) {
b = append(b, x)
}
}
So in this case a function which deletes certain elements could look like this:
func removeApplications(apps []Applications) []Applications {
filteredApps := apps[:0]
for _, app := apps {
if !removeApp {
filteredApps = append(filteredApps, app)
}
}
return filteredApps
}
答案4
得分: 1
我认为简单的方法是:
var (
slice = []int{1,2,3,4,5}
pos int
)
for _, i := range slice {
if i == 3 {
slice = append(slice[:pos], slice[pos+1:]...)
if pos > 0 {
pos = pos - 1
}
continue
}
pos++
}
这是一个示例链接:
https://play.golang.org/p/pK3B5Mii9k
英文:
I think the simple way is
var (
slice = []int{1,2,3,4,5}
pos int
)
for _, i := range slice {
if i == 3 {
slice = append(slice[:pos], slice[pos+1:]...)
if pos > 0 {
pos = pos - 1
}
continue
}
pos++
}
here is...
https://play.golang.org/p/pK3B5Mii9k
答案5
得分: 0
要从结构体中删除特定的切片,我们需要运行一个for循环来查找该特定的切片并删除它。
例如:
type variable struct {
Id int `json:"id"`
Message string `json:"message"`
}
var mssg = []variable{
{Id: 1, Message: "success"},
{Id: 2, Message: "failed"},
}
for i, a := range mssg {
if a.Message == "success" {
mssg = append(mssg[:i], mssg[i+1:]...)
fmt.Println(mssg)
}
}
以上代码会删除mssg
切片中Message
字段为"success"的结构体。
英文:
To remove a particular slice from a struct we need to run a for-loop to find that particular slice and delete it
>for example:
type variable struct {
Id int `json:"id"`
Message string `json:"message"`
}
var mssg = []variable{
{Id: 1, Message: "success"},
{Id: 2, Message: "failed"}
}
for i, a := range mssg {
if a.Message == "success" {
mssg = append(mssg[:i], mssg[i+1:]...)
fmt.Println(mssg)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论