go语言切片去重的3种方式

 更新时间:2024年08月19日 11:26:19   作者:tekin  
go语言中的切片是使用非常频繁的一个数据结构,本文主要介绍了go语言切片去重的3种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

go语言中的切片是使用非常频繁的一个数据结构,对于他的去重,我们可以有以下3种方式

1. 切片slice去重

利用map的key不能重复的特性+append函数  一次for循环搞定

这个模式时间复杂度最低,效率最高, 如果go版本大于1.21推荐使用这种方式的泛型参数版本

// 改进版的slice去重
func UniqueSliceInt64(ss []int64) []int64 {
	newSS := make([]int64, 0)  // 返回的新切片
	m1 := make(map[int64]byte) //用来去重的临时map
	for _, v := range ss {
		if _, ok := m1[v]; !ok {
			m1[v] = 1
			newSS = append(newSS, v)
		}
	}
	return newSS
}

泛型参数版本,需要go版本大于1.21 否则不能使用泛型参数

// 切片去重升级版 泛型参数 利用map的key不能重复的特性+append函数  一次for循环搞定
func Unique[T cmp.Ordered](ss []T) []T {
	size := len(ss)
	if size == 0 {
		return []T{}
	}
	newSlices := make([]T, 0) //这里新建一个切片,大于为0, 因为我们不知道有几个非重复数据,后面都使用append来动态增加并扩容
	m1 := make(map[T]byte)
	for _, v := range ss {
		if _, ok := m1[v]; !ok { //如果数据不在map中,放入
			m1[v] = 1                        // 保存到map中,用于下次判断
			newSlices = append(newSlices, v) // 将数据放入新的切片中
		}
	}
	return newSlices
}

2. 切片去重

利用map的key不能重复的特性 2次for循环

下面这个使用了泛型参数

//go版本大于1.21的情况,可以使用泛型参数

// 切片去重  泛型参数 利用map的key不能重复的特性 2次for循环
func Unique1[T cmp.Ordered](ss []T) []T {
	size := len(ss)
	if size == 0 {
		return []T{}
	}
	// 这个地方利用了map数据的key不能重复的特性,将切片的值当做key放入map中,达到去重的目的
	m1 := make(map[T]byte)
	for i := 0; i < size; i++ {
		m1[ss[i]] = 1
	}
	// 创建一个切片,长度为去重后的数据长度
	newSS := make([]T, len(m1))
	idx := 0
	for key := range m1 { // 循环map, 将key放入到切片中
		newSS[idx] = key
		idx++
	}
	return newSS
}

cmp.Ordered泛型参数约束接口参考    注意上面的泛型参数约束 cmp.Ordered 是一个专门用于泛型类型约束的接口定义, 需要go版本大于1.21才能使用

type Ordered interface {
    ~int | ~int8 | ~int16 | ~int32 | ~int64 |
        ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
        ~float32 | ~float64 |
        ~string
}

3. 切片去重

双层for循环模式

这种方式方式直观,但是时间复杂度较高!

// 切片去重 双层for循环模式
func Unique0(ss []int64) (newSS []int64) {
	newSS = make([]int64, 0)
	for i := 0; i < len(ss); i++ {
		repeat := false
		for j := i + 1; j < len(ss); j++ {
			if ss[i] == ss[j] {
				repeat = true
				break
			}
		}
		if !repeat {
			newSS = append(newSS, ss[i])
		}
	}
	return
}

总结

对于golang的切片去重,效率最高的方式为map+append函数的方式,因为他们的时间复杂度是最低的,对于go版本大于1.21的推荐使用泛型参数的切片去重,这样一个函数就可以解决所有类型的切片去重问题,高效精简! 

到此这篇关于go语言切片去重的3种方式 的文章就介绍到这了,更多相关go语言切片去重内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • 浅谈Go语言多态的实现与interface使用

    浅谈Go语言多态的实现与interface使用

    如果大家系统的学过C++、Java等语言以及面向对象的话,相信应该对多态不会陌生。多态是面向对象范畴当中经常使用并且非常好用的一个功能,它主要是用在强类型语言当中,像是Python这样的弱类型语言,变量的类型可以随意变化,也没有任何限制,其实区别不是很大
    2021-06-06
  • 浅谈golang 中time.After释放的问题

    浅谈golang 中time.After释放的问题

    这篇文章主要介绍了浅谈golang 中time.After释放的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • Go日志框架zap增强及源码解读

    Go日志框架zap增强及源码解读

    这篇文章主要为大家介绍了Go日志框架zap增强及源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Golang实现单链表的示例代码

    Golang实现单链表的示例代码

    本文主要介绍了Golang实现单链表的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • 一文带你了解Golang中select的实现原理

    一文带你了解Golang中select的实现原理

    select是go提供的一种跟并发相关的语法,非常有用。本文将介绍 Go 语言中的 select 的实现原理,包括 select 的结构和常见问题、编译期间的多种优化以及运行时的执行过程
    2023-02-02
  • Golang使用CGO与Plugin技术运行加载C动态库

    Golang使用CGO与Plugin技术运行加载C动态库

    这篇文章主要介绍了Golang使用CGO与Plugin技术运行加载C动态库,Golang 程序在运行时加载C动态库的技术,跳过了Golang项目编译阶段需要链接C动态库的过程,提高了Golang项目开发部署的灵活性
    2022-07-07
  • 让go程序以后台进程或daemon方式运行方法探究

    让go程序以后台进程或daemon方式运行方法探究

    本文探讨了如何通过Go代码实现在后台运行的程序,最近我用Go语言开发了一个WebSocket服务,我希望它能在后台运行,并在异常退出时自动重新启动,我的整体思路是将程序转为后台进程,也就是守护进程(daemon)
    2024-01-01
  • 详解Golang中Channel的原理和使用技巧

    详解Golang中Channel的原理和使用技巧

    Channel管道提供了一种机制,它在两个并发执行的协程之间进行同步,并通过传递与该管道元素类型相符的值来进行通信。本文主要介绍了Channel的原理和使用技巧,需要的可以参考一下
    2022-11-11
  • go语言字符串的拼接和切片方法总结

    go语言字符串的拼接和切片方法总结

    在go语言中,因为字符串只能被访问,不能被修改,所以进行字符串拼接的时候,golang都需要进行内存拷贝,造成一定的性能消耗,这篇文章主要给大家介绍了关于go语言字符串的拼接和切片的相关资料,需要的朋友可以参考下
    2022-11-11
  • Go语言实现socket实例

    Go语言实现socket实例

    这篇文章主要介绍了Go语言实现socket的方法,实例分析了socket客户端与服务器端的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02

最新评论