Go 如何切片以消除相同切片中的匹配值
我正在寻找一种简单的方法来迭代一个切片,并在当前切片中存在的每个值上,从另一个切片中删除元素 我有一个结构:Go 如何切片以消除相同切片中的匹配值,go,Go,我正在寻找一种简单的方法来迭代一个切片,并在当前切片中存在的每个值上,从另一个切片中删除元素 我有一个结构: a := enter{ uid: 1234, status: []StatusEntry{ { rank: 1, iterate: ierationState_Ongoing, }, {
a := enter{
uid: 1234,
status: []StatusEntry{
{
rank: 1,
iterate: ierationState_Ongoing,
},
{
rank: 2,
iterate: ierationState_Completed,
},
},
}
在我的.go文件中,我有一个常量
Steps = [5]int64{0,1,2,3,4}
根据我的要求,我想复制另一个变量中的步骤并执行删除操作:
Steps2 := Steps // Make a copy of Steps
for _, element := enter.status {
// Remove that element from Steps
}
但我发现很难做到这一点,因为Golang没有给我直接的方法来迭代并从步骤中删除enter.status中的每个元素
我尝试了多种方法,如在各种stackoverflow答案上发布的创建removeIndex函数,如下所示:
for i, element := enter.status {
Steps2 = removeIndex(enter.status, i)
}
但是使用它是没有意义的,因为我试图从步骤2中删除一个匹配的值(元素),而不是一个特定的索引(例如索引5)
基本上,对于sliceenter.status中的每个元素,我想从slice步骤2中删除该元素/值,请小心:
这是一个数组(由5个int
s组成),不是一个切片。以及:
如果Steps
是一个切片,那么这将复制切片头而不复制底层数组
在任何情况下,给定类型为T
和长度为len的某个切片s
,如果允许修改s
,并且顺序相关,则通常需要使用此算法:
func trim(s []T) []T {
out := 0
for i := range s {
if keep(s[i]) {
s[out] = s[i]
out++
}
}
return s[:out]
}
其中,keep
是决定是否保留元素的布尔函数。要使其产生一个新的片,请在开始时分配一个适当长度的输出片(len)
),并可以选择在以后缩小它,或者,如果希望抛出大多数元素,则在开始时将其置空并使用append
当keep
函数为“输出片中某个字段的值与任何先前保留字段的值不匹配”且该字段的类型可用作键类型时,您可以使用简单的map[T2]struct{}
来确定该值是否已出现:
seen := make(map[T2]struct{}, len(s))
然后,keep
测试和复制序列变为:
_, ok := seen[s[i].field]
if !ok {
seen[s[i].field] = struct{}{}
s[out] = s[i]
out++
}
此处所见的的初始大小根据保留大多数值的理论进行了优化;如果大多数值将被丢弃,则最初将贴图设置为空或小
func trim(s []T) []T {
out := 0
for i := range s {
if keep(s[i]) {
s[out] = s[i]
out++
}
}
return s[:out]
}
seen := make(map[T2]struct{}, len(s))
_, ok := seen[s[i].field]
if !ok {
seen[s[i].field] = struct{}{}
s[out] = s[i]
out++
}