从Go中的切片中删除已知元素

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

Delete known element from slice in Go

问题

我正在尝试使用slices包从一个chan []byte的切片中删除元素。但是我想删除一个已知的值,而不是使用位置来删除,就像这里所示:https://stackoverflow.com/questions/37334119/how-to-delete-an-element-from-a-slice-in-golang。

import "golang.org/x/exp/slices"

var receiverChannels []chan []byte

channel := make(chan []byte)
receiverChannels = append(receiverChannels, channel)

receiverChannels = slices.Delete(receiverChannels, channel)
英文:

I am trying to use the slices package to delete a chan []byte from a slice of them.
But I have a known value that I want to remove instead of using the position like it shows here https://stackoverflow.com/questions/37334119/how-to-delete-an-element-from-a-slice-in-golang.

import "golang.org/x/exp/slices"

var receiverChannels []chan []byte

channel := make(chan []byte)
receiverChannels = append(receiverChannels, channel)

receiverChannels = slices.Delete(receiverChannels, channel)

答案1

得分: 1

Go 1.18 带有类型参数的解决方案:

func Delete[T comparable](collection []T, el T) []T {
    idx := Find(collection, el)
    if idx > -1 {
        return slices.Delete(collection, idx, idx+1)
    }
    return collection
}

func Find[T comparable](collection []T, el T) int {
    for i := range collection {
        if collection[i] == el {
            return i
        }
    }
    return -1
}

这段代码使用了类型参数(Type Parameters)来实现泛型编程。Delete 函数用于从切片中删除指定元素,Find 函数用于查找元素在切片中的索引位置。这两个函数都可以适用于不同类型的切片,只需在调用时指定相应的类型参数即可。

英文:

Go 1.18 solution with type parameters:

func Delete[T comparable](collection []T, el T) []T {
    idx := Find(collection, el)
    if idx > -1 {
        return slices.Delete(collection, idx, idx+1)
    }
    return collection
}

func Find[T comparable](collection []T, el T) int {
    for i := range collection {
        if collection[i] == el {
            return i
        }
    }
    return -1
}

答案2

得分: 0

如果切片的顺序不重要,你可以使用映射(map)代替:

var receiverChannels = make(map[chan []byte]struct{})

channel := make(chan []byte)
receiverChannels[channel] = struct{}{}
delete(receiverChannels, channel)

否则,你需要一个find辅助函数:

func find(channels []chan []byte, ch chan []byte) int {
   for i := range channels {
     if channels[i] == ch {
        return i
     }
   }
  return -1
}

或者一个通用的find函数:

func find[T comparable](slice []T, item T) int {
	for i := range slice {
		if slice[i] == item {
			return i
		}
	}
	return -1
}

如果你需要保留切片但顺序不重要,你可以简单地将最后一个元素移动到指定位置并截断切片:

i := find(receiverChannels, channel)
if i != -1 {
  if i < len(receiverChannels)-1 {
    receiverChannels[i] = receiverChannels[len(receiverChannels)-1]
  }
  receiverChannels = receiverChannels[:len(receiverChannels)-1]
}

最后,如果顺序很重要:

i := find(receiverChannels, channel)
if i != -1 {
   receiverChannels = append(receiverChannels[:i], receiverChannels[i+1:]...)
   receiverChannels = receiverChannels[:len(receiverChannels)-1]
}
英文:

If the ordering of the slice is not important, you can use a map instead:

var receiverChannels = make(map[chan []byte]struct{})

channel:=make(chan []byte)
receiverChannels[channel]=struct{}{}
delete(receiverChannels,channel)

Otherwise, you need a find helper function:

func find(channels []chan []byte, ch chan []byte) int {
   for i:=range channels {
     if channels[i]==ch {
        return i
     }
   }
  return -1
}

Or a generic find:

func find[T comparable](slice []T, item T) int {
	for i := range slice {
		if slice[i] == item {
			return i
		}
	}
	return -1
}

If you need to keep a slice but ordering is not important, you can simply move the last element and truncate the slice:

i:=find(receiverChannels, channel)
if i!=-1 {
  if i&lt;len(receiverChannels)-1 {
    receiverChannels[i]=receiverChannels[len(receiverChannels)-1]
  }
  receiverChannels=receiverChannels[:len(receiverChannels)-1]
}

Last, if ordering is important:

i:=find(receiverChannels, channel)
if i!=-1 {
   receiverChannels=append(receiverChannels[:i], receiverChannels[i+1:]...)
   receiverChannels=receiverChannels[:len(receiverChannels)-1]
}

huangapple
  • 本文由 发表于 2022年6月3日 10:38:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/72484175.html
匿名

发表评论

匿名网友

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

确定