go 切片进行链式操作并支持泛型

背景:

      由于团队不是专业级别的go开发人员,主开发还是java,用惯了java的lambda表达式特别是流式操作, 所以在用go语言时,发现切片处理起来比较麻烦,看看能不能支持类似流式操作,我这边就研究了下这块业务,发现是可以实现的,同时要支持所有类型,所以必然要支持泛型才可以,背景介绍完,开始正题:

定义泛型的类型形参列表:

// SliceAble
//
//	@Description: 泛型,如果需要支持其他类型,请自行添加
//	@Author  zhaosy
//	@date  2024-07-12 17:07:22
type SliceAble interface {
	Person | string | int
}

定义切片类型


// Slice
// 定义新切片类型
type Slice[T SliceAble] []T

// NewSlice [T SliceAble]
//
//	@Author  zhaosy
//	@Description: newSlice
//	@date  2024-07-13 13:22:23
func NewSlice[T SliceAble](arr []T) Slice[T] {
     //这里为了不影响原始切片数据,所以进行copy,如果不关心可以删除直接返回arr即可
	copyArr := make([]T, len(arr), len(arr))
	copy(copyArr, arr)
	return copyArr
}

// Filter
//
//	@Author  zhaosy
//	@Description: 过滤,demo:
//	people := []lang.Person{
//		{"Alice", 45},
//		{"Elizabeth", 75},
//		{"Alice", 25},
//		{"Bob", 30},
//		{"Alice", 2},
//		{"Bob", 4},
//		{"Colin", 5},
//		{"Elizabeth", 34},
//	}
//
//	p := lang.NewSlice(people).Filter(func(i lang.Person) bool {
//		return i.Age > 30
//	})
//
//	fmt.Println(p) //[{Alice 45} {Elizabeth 75} {Elizabeth 34}]
//	@date  2024-07-13 11:48:46
func (s Slice[T]) Filter(f func(T) bool) Slice[T] {
	var temp Slice[T]
	for _, v := range s {
		b := f(v)
		if b {
			temp = append(temp, v)
		}

	}
	return temp
}

// Sort
//
//	@Author  zhaosy
//	@Description: 排序:
//	排序规则根据函数放回的bool类型进行排序,demo:
//	people := []lang.Person{
//		{"Alice", 45},
//		{"Elizabeth", 75},
//		{"Alice", 25},
//		{"Bob", 30},
//		{"Alice", 2},
//		{"Bob", 4},
//		{"Colin", 5},
//		{"Elizabeth", 34},
//	}
//	lang.NewSlice(people).Sort(func(s lang.Slice[lang.Person], i, j int) bool {
//		return s[i].Age > s[j].Age
//	})
//	fmt.Println(people) //结果:[{Elizabeth 75} {Alice 45} {Elizabeth 34} {Bob 30} {Alice 25} {Colin 5} {Bob 4} {Alice 2}]
//
//	@date  2024-07-13 11:41:14
func (s Slice[T]) Sort(f func(s Slice[T], i, j int) bool) Slice[T] {
	sort.SliceStable(s, func(i, j int) bool {
		return f(s, i, j)
	})
	return s
}

// Append
//
//	@Author  zhaosy
//	@Description: 追加元素;采用go 底层切片append方式
//	@date  2024-07-13 13:13:09
func (s Slice[T]) Append(newObj T) Slice[T] {
	s = append(s, newObj)
	return s
}

// OnePointerObj
//
//	@Author  zhaosy
//	@Description: 返回单条数据实例,是指针类型,且判断是否为空
//	@date  2024-07-13 13:13:41
func (s Slice[T]) OnePointerObj() *T {
	if len(s) == 0 {
		return nil
	}
	return &s[0]
}


// OnePointerObj
//
//	@Author  zhaosy
//	@Description: 返回json字符串,如果为空,直接返回空字符串
//	@date  2024-07-13 13:47:41
func (s Slice[T]) ToJsonStr() string {
	b, err := json.Marshal(s)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	return string(b)
}

测试:

import (
	"fmt"
	"testing"
)

type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func TestSlice_All(t *testing.T) {

	people := []Person{
		{"张三", 45},
		{"李四", 2},
		{"王五", 25},
		{"小明", 15},
		{"小红", 2},
		{"小蓝", 7},
		{"小白", 5},
		{"小花", 34},
	}
	fmt.Println("原始数据:", people)
	//需求:根据年龄进行升序排序
	p := NewSlice(people).Sort(func(s Slice[Person], i, j int) bool {
		return s[i].Age < s[j].Age
	})
	fmt.Println("排序后:", p) //结果:[{李四 2} {小红 2} {小白 5} {小蓝 7} {小明 15} {王五 25} {小花 34} {张三 45}]

	//需求:过滤掉小于18岁的信息
	p = NewSlice(people).Filter(func(pe Person) bool {
		return pe.Age > 18
	})
	fmt.Println("过滤18岁以后的:", p) //结果:[{张三 45} {王五 25} {小花 34}]

	//需求:向切片最后一个追加一个元素
	p = NewSlice(people).Append(Person{
		Name: "李玲",
		Age:  23,
	})
	fmt.Println("追加元素后:", p) //结果:[{张三 45} {李四 2} {王五 25} {小明 15} {小红 2} {小蓝 7} {小白 5} {小花 34} {李玲 23}]

	//需求:获取切片第一个(这块目的是经过其他方法处理过后,直接获取第一个,比较简单直接)
	one := NewSlice(people).OnePointerObj()
	fmt.Println("第一个元素:", *one) //结果:{张三 45}

	//来一个比较常用的链式需求,需求:新增一个元素,并输出大于18岁且按照年龄进行升序排序的列表,最后以json方式输出
	jsonStr := NewSlice(people).Append(Person{"李华", 35}).Sort(func(s Slice[Person], i, j int) bool {
		return s[i].Age < s[j].Age
	}).Filter(func(pe Person) bool {
		return pe.Age > 18
	}).ToJsonStr()
	fmt.Println("结果:", jsonStr) //结果:[{"name":"王五","age":25},{"name":"小花","age":34},{"name":"李华","age":35},{"name":"张三","age":45}]

	//后期有其他需求可以继续添加,这样就比较简单了
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/801279.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么是STM32?嵌入式和STM32简单介绍

1、嵌入式和STM32 1.1.什么是嵌入式 除了桌面PC之外&#xff0c;所有的控制类设备都是嵌入式 嵌入式系统的定义&#xff1a;“用于控制、监视或者辅助操作机器和设备的装置”。 嵌入式系统是一个控制程序存储在ROM中的嵌入式处理器控制板&#xff0c;是一种专用的计算机系统。…

启动react 18.2.x项目报node错误

1、项目启动报错&#xff0c;node版本问题 可以考虑把node版本降低一点&#xff0c;我当时node版本是20.xx 后面我把本本降到16.13.1 2、tsconfig.json的飘红问题 这里提示的是这个字段已经不用了&#xff0c;建议删除该字段&#xff0c;所以删除该字段就好&#xff0c;其实…

[经典]Axrue部件库:Android系统部件

部件库预览链接&#xff1a;&#xff08;请与班主任联系获取文档&#xff09; 支持版本: Axrure RP 8 文件大小: 1200KB 模板目录 黑、白两种UI风格 每天 文档内容介绍 免费领取资料 “210630” 领取

JavaScript object 数据更新方法

https://andi.cn/page/621560.html

JS-11G1端子排静态时间继电器 约瑟JOSEF

JS-11G端子排静态时间继电器 系列型号&#xff1a; JS-11G1端子排静态时间继电器&#xff1b;JS-11G2端子排静态时间继电器; JS-11G3端子排静态时间继电器; JS-11G4端子排静态时间继电器; JS-11G5端子排静态时间继电器;JS-11G7端子排静态时间继电器; JS-11G9端子排静态时间…

沙袋装袋机的原理和特点_鼎跃安全

在现代工业和建筑领域&#xff0c;沙子等散状物料的包装是一个必不可少的环节。传统的手工包装方式效率低下且劳动强度大&#xff0c;而沙袋装袋机的出现则极大地提高了包装效率和质量。 一、沙袋装袋机的工作原理 沙子通过输送系统从储料仓输送到装袋机的料斗中。输送系统设计…

SpringBoot中动态注册Bean的方式

测试环境&#xff0c;本文源码 Java&#xff1a;8SpringBoot&#xff1a;2.5.14示例场景&#xff1a;动态注册ProxyServlet&#xff0c;间接实现类似于Nginx的反向代理功能 先理解如何实现动态注册 Bean 。 由于在 SpringBoot 中&#xff0c;先进行 Bean 的定义&#xff0c;…

道路巡检准确率优于90%,千寻驰观是怎么做到的?

在7月初落下帷幕的2024世界人工智能大会上&#xff0c;人形机器人十八罗汉齐聚现场&#xff0c;“百模大战”精彩开演&#xff0c;还有多种大模型在产业端应用和落地&#xff0c;AI浪潮席卷而来。千寻位置携北斗时空智能AI应用千寻驰观产品亮相大会&#xff0c;备受瞩目。 2024…

释放DOE的能量,快速确定最佳工艺设置,节省时间、成本和资源

您是否希望降低成本、提高生产效率&#xff0c;并最大限度地减少行业对环境的影响&#xff1f; 所有行业&#xff0c;尤其是钢铁、铝、水泥和石化等能源密集型行业&#xff0c;都面临着应对这些挑战的持续压力。供应链压力、可持续发展、严格的监管环境、日益增长的消费者预期…

在前端vue3 开发媒体查询代码 实现 响应式布局(js 和css 方式)

在上一篇文章中 我介绍了一下 媒体查询的知识以及概念 我只介绍了在html css3 中的使用方式以及书写 下面我来简单来演示一下 在vue3 中怎么使用这个 其实都一样的 只是.vue 的文件 我用的是ant-design-vue3 的前端web端框架 用这个来演示 一. css样式媒体查询 目前的框架 是…

mysql中的存储过程

存储过程的作用:有助于提高应用程序的性能。存储过程可以不必发送多个冗长的SQL语句 废话不说多&#xff0c;直接实操 ##实现num的相加 delimiter $$ CREATE PROCEDURE test1 () begindeclare num int default 0; -- 声明变量,赋默认值为0select num20;end $$ delimiter ; …

誉天教育与武汉晴川学院携手开展鸿蒙实训营,共筑鸿蒙生态新篇章!

在数字经济蓬勃发展的今天&#xff0c;鸿蒙系统作为华为自主研发的操作系统&#xff0c;正逐步构建起一个开放、协同、共赢的生态体系。为了进一步推动鸿蒙生态的繁荣发展&#xff0c;培养更多具备鸿蒙原生应用开发能力的专业人才&#xff0c;誉天教育与武汉晴川学院强强联合&a…

聚类分析方法(三)

目录 五、聚类的质量评价&#xff08;一&#xff09;簇的数目估计&#xff08;二&#xff09;外部质量评价&#xff08;三&#xff09;内部质量评价 六、离群点挖掘&#xff08;一&#xff09;相关问题概述&#xff08;二&#xff09;基于距离的方法&#xff08;三&#xff09;…

内网服务器通过squid代理访问外网

一、背景 现在要对172.16.58.158服务器进行openssh升级操作,我用之前写好的升级脚本执行后,发现没有备份旧的ssh程序文件,然后还卸载了oenssl-devel,然后我发现其他服务器ssh该服务器失败。同时脚本执行时报错“ configure: error: *** zlib.h missing - please install first …

Modbus - 笔记

1 Modbus Poll/Slave 模拟器使用教程 Modbus Poll/Slave 模拟器使用教程_modbus poll 使用教程-CSDN博客 https://item.jd.com/67488830087.html 2 一文秒懂串口、COM口、TTL、RS-232、RS-485区别 一文秒懂串口、COM口、TTL、RS-232、RS-485区别_电平 3 串口的学习 http…

安灯系统在电力设备制造业中的应用效果

安灯系统作为面向制造业生产现场的专门应用软硬件系统&#xff0c;在电力设备制造企业中发挥着重要的作用。作为精益制造执行的核心工具&#xff0c;安灯系统为企业提供了快速联络生产、物料、维修、主管等部门的功能&#xff0c;以实时掌控和管理生产线状况&#xff0c;实现生…

FlashAttention3:“GEMM”就是比较快!

阅读文章之前请温习以下四篇文章&#xff0c;避免云里雾里&#xff1a; 轻松读懂FlashAttention上<矩阵分块加载&#xff0c;改写softmax算法> 轻松读懂FlashAttention下 轻松读懂FlashAttention-2<优化循环体&#xff0c;减少非矩阵运算> GPU的基础认知<GE…

绘制science研究区域概况图

Python绘制研究区域概况图&#xff1a; import numpy as np import matplotlib.pyplot as plt from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter import cartopy.crs as ccrs import cartopy.feature as cfeature from cartopy.io.shapereader import R…

【螺旋矩阵】python刷题记录

目录 题目&#xff1a; 思路&#xff1a; 上代码&#xff1a; 结果&#xff1a; 大佬题解&#xff1a; 思路&#xff1a; 代码&#xff1a; 结果&#xff1a; 题目&#xff1a; 这题 模拟 来做 思路&#xff1a; 方向转换&#xff1a;使用矩阵&#xff08;4个元素&…

el-table的selection多选表格改为单选

需求场景: 选择表格数据时&#xff0c;需要控制单条数据的操作按钮是否禁用。 效果图: html代码: <div><el-tableref"multipleTable":data"tableData"tooltip-effect"dark"style"width: 100%"selection-change"handl…