Go删除切片元素的另一种姿势

首先整理一下删除切片的常用方法

现在有一个切片slice

  • slice = append(slice[:n]:slice[n+1])
  • slice = slice[1:]等等

本文针对一个特殊场景

现有切片A,B,切片B中的部分元素是切片A的子集,求A删除B中子集后的部分

先上常规思路代码:

for k, v := range A {
   	for _, m := range B {
   		if v == m {
   			switch k {
   			case 1:
   				A = A[1:]
   			case len(A):
   				A = A[:len(A)-1]
   			default:
   				A = append(A[:k], A[k+1:]...)
   			}
   		}
   	}
   }

乍一看,简单粗暴,万无一失,然而当我们运行之后,一定会panic,原因是数组越界

原因很简单,切片A的实际长度一直在减少,然而在循环中的index并不会,在操作A = append(A[:k], A[k+1:]...)一定会造成越界

这个时候如果你去百度《go删除切片元素》,那么一定会得到以下答案

	A = A[1:]
	A = A[:len(A)-1]
	A = append(A[:k], A[k+1:]...)

本文提供一种方式,(注:仅为分享该方式,并不仅有此方式)

在go语言中,map一直是slice的好朋友,map与slice结合可是实现很多功能,例如去重等等,但是却往往却忽略了另一项list(链表)

在Go语言中container/list提供了链表结构,链表删除节点的效率无疑是要比slice高很多的,关于该包的详细内容可自行百度,但是官方提供的包对于pop操作并不是很支持,由于本人一直在使用GoFrame框架,这里提供github.com/gogf/gf/container/glist,也可以去GoFrame官网自行了解

废话有点多,开始操作

  • 将B转换为map
C := make(map[string]int)
	for _,v := range B{
		C[v] = 1  //值并不重要
	}
  • 将只属于A的元素添加到list
list := glist.New()
	for _, k := range A{
		_, ok := C[k] //判断是否已经存在
		if !ok {
			list.PushBack(k) //不存在则加入list
		}
	}
  • 得到需要的数据list,根据场景可以方便的对list进行操作,已经变换为想要的数据结构
list.PopFrontAll()
list.PopBackAll()

关于glist的介绍:https://goframe.org/pages/viewpage.action?pageId=7297433

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值