当前位置: 首页 > news >正文

golang使用泛型实现mapreduce操作

1.使用面向对象的方式写

package streamimport ("fmt""log""reflect""sort""strconv""strings"
)type Stream[T any] struct {data      []TkeyBy     stringsortByNum stringsortByStr []string
}func FromElement[T any](data []T) *Stream[T] {return &Stream[T]{data: data,}
}// 过滤算子
type filterfunc[F any] func(F) boolfunc (s *Stream[T]) Filter(filterFun filterfunc[T]) *Stream[T] {var new []Tfor _, item := range s.data {isfiltered := filterFun(item)if isfiltered {continue}new = append(new, item)}s.data = newreturn s
}// 单行处理
type mapfunc[F any] func(F) Ffunc (s *Stream[T]) Map(mapFun mapfunc[T]) *Stream[T] {for idx, item := range s.data {ret := mapFun(item)s.data[idx] = ret}return s
}// 排序
func (s *Stream[T]) SortByNum(key string) *Stream[T] {s.sortByNum = keyif len(s.sortByStr) > 0 {s.sortByStr = nil}return s
}// 每次排序只能使用一种排
func (s *Stream[T]) SortByStr(keys ...string) *Stream[T] {s.sortByStr = keysif s.sortByNum != "" {s.sortByNum = ""}return s
}func (s *Stream[T]) Sort(esc bool) *Stream[T] {if s.sortByNum == "" && len(s.sortByStr) == 0 {log.Println("please call SortBy() before sort()")return s}if s.sortByNum != "" {sort.Slice(s.data, func(i, j int) bool {v := reflect.ValueOf(s.data[i]).Elem()field := v.FieldByName(s.sortByNum)if !field.IsValid() {log.Panicf("field=%s not valid", s.sortByNum)}idata := fmt.Sprintf("%v", field.Interface())num, err := strconv.ParseInt(idata, 10, 64)if err != nil {log.Panic("please use num when use sortByNum", idata)}v1 := reflect.ValueOf(s.data[j]).Elem()field1 := v1.FieldByName(s.sortByNum)if !field1.IsValid() {log.Panicf("field=%s not valid", s.sortByNum)}jdata := fmt.Sprintf("%v", field1.Interface())num1, err := strconv.ParseInt(jdata, 10, 64)if err != nil {log.Panic("please use num when use sortByNum")}if esc {return num < num1} else {return num > num1}})}if len(s.sortByStr) > 0 {sort.Slice(s.data, func(i, j int) bool {var ifinalv, jfinalv stringfor _, key := range s.sortByStr {v := reflect.ValueOf(s.data[i]).Elem()field := v.FieldByName(key)if !field.IsValid() {log.Panicf("field=%s not valid", key)}idata := fmt.Sprintf("%v", field.Interface())ifinalv = ifinalv + idata}for _, key := range s.sortByStr {v := reflect.ValueOf(s.data[j]).Elem()field := v.FieldByName(key)if !field.IsValid() {log.Panicf("field=%s not valid", key)}jdata := fmt.Sprintf("%v", field.Interface())jfinalv = jfinalv + jdata}// i 大于j的话 返回1 所以正序需要返回falseret := strings.Compare(ifinalv, jfinalv)if esc {return ret < 0}return ret >= 0})}return s
}// 设置聚合的key
func (s *Stream[T]) KeyBy(key string) *Stream[T] {s.keyBy = keyreturn s
}// reduce
// 暂时木有办法改变输出的结构
type reducefunc[F any] func([]F) Ffunc (s *Stream[T]) Reduce(reduceFun reducefunc[T]) *Stream[T] {if s.keyBy == "" {log.Fatal("please call keyby() before reduce()")return nil}var cache = make(map[string][]T)defer func() {cache = nil}()for _, item := range s.data {v := reflect.ValueOf(item).Elem()field := v.FieldByName(s.keyBy)key := field.String()lis, ok := cache[key]if !ok {lis = make([]T, 0)}lis = append(lis, item)cache[key] = lis}var new []Tfor _, lis := range cache {ret := reduceFun(lis)new = append(new, ret)}s.data = newreturn s
}// 返回个数
func (s *Stream[T]) Limit(n int) []T {if n > len(s.data) {n = len(s.data)}return s.data[0:n]
}func (s *Stream[T]) Print() {for idx, item := range s.data {log.Printf("idx=%d val=%v", idx, item)}
}func (s *Stream[T]) Result() []T {return s.data
}

测试例子

func TestTostream(t *testing.T) {FromElement([]*Student{&Student{"xyf", "数学", 101},&Student{"xyf", "语文", 108},&Student{"xyf", "外语", 101},}).Map(func(st *Student) *Student {st.Score = st.Score + 10return st}).Filter(func(st *Student) bool {return st.Name == "xyf"}).// SortByStr("Name", "Subject").SortByNum("Score").Sort(false).KeyBy("Name").Reduce(func(st []*Student) *Student {var ret = &Student{Name:    st[0].Name,Subject: "all",}for _, item := range st {ret.Score = ret.Score + item.Score}return ret}).Print()
}

 缺点:golang有点挫的在于不能在方法里面返回新的泛型类型,比如从student返回一个int类型。虽然能通过在struct定义俩个类型 但是万一要生成第三种类型就无能为力了,不可能一直往后加类型吧(这会导致定义类型超级长 写起来超级丑)。

2.通过函数的方式实现(简单举个例子)

type StreamV2[T any] struct {data []T
}func (s StreamV2[T]) Print() {for i, item := range s.data {log.Println("idx=", i, " value=", item)}
}func FromElementV2[T any](data []T) Stream[T] {return Stream[T]{data: data,}
}func Map[T any, K any](source Stream[T], mapfunc func(data T) K) StreamV2[K] {var ret []Kfor _, item := range source.data {ret1 := mapfunc(item)ret = append(ret, ret1)}return StreamV2[K]{data: ret,}
}

测试

func TestTostreamv2(t *testing.T) {stream1 := FromElementV2([]*Student{&Student{"xyf", "数学", 101},&Student{"xyf", "语文", 108},})stream2 := Map(stream1, func(f *Student) int {return f.Score})stream2.Print()
}

优缺点:这种方式能够将一种容器类型转化为另一种。缺点就是写过java的会吐血(因为搞大数据的朋友都喜欢使用类似builder模式的写法)

相关文章:

golang使用泛型实现mapreduce操作

1.使用面向对象的方式写 package streamimport ("fmt""log""reflect""sort""strconv""strings" )type Stream[T any] struct {data []TkeyBy stringsortByNum stringsortByStr []string }func FromElem…...

2023华数杯数学建模C题思路分析 - 母亲身心健康对婴儿成长的影响

# 1 赛题 C 题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c; 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况&#xff0c;如抑郁、焦虑、 压力等&#xff0c;可能会对婴儿的认知、情…...

【汇总】解决Ajax请求后端接口,返回ModelAndView页面不跳转

【汇总】解决Ajax请求后端接口&#xff0c;返回ModelAndView不跳转 问题发现问题解决方法一&#xff1a;直接跳转到指定URL&#xff08;推荐&#xff09;方法二&#xff1a;将返回的html内容&#xff0c;插入到页面某个元素中方法三&#xff1a;操作文档流方法四&#xff1a;使…...

网络安全进阶学习第九课——SQL注入介绍

文章目录 一、什么是注入二、什么是SQL注入三、SQL注入产生的原因四、SQL注入的危害五、SQL注入在渗透中的利用1、绕过登录验证&#xff1a;使用万能密码登录网站后台等。2、获取敏感数据3、文件系统操作4、注册表操作5、执行系统命令 六、如何挖掘SQL注入1、SQL注入漏洞分类按…...

一个计算机专业的学生数据结构这门课学到什么程度才能算学的还不错?

数据结构之所以重要是因为它处于算法中的基础地位&#xff0c;与解决实际问题关系密切&#xff1b;而之所以不重要是因为课本上能学到的所有实现都已经有人造过轮子了&#xff0c;甚至已经作为很多语言的标准API存在了。 换句话来说&#xff0c;在以后的编码生涯中&#xff0c…...

[语义分割] ASPP不同版本对比(DeepLab、DeepLab v1、DeepLab v2、DeepLab v3、DeepLab v3+、LR-ASPP)

1. 引言 1.1 本文目的 本文主要对前段时间学习的 ASPP 模块进行对比&#xff0c;涉及到的 ASPP 有&#xff1a; ASPP in DeepLab v2&#xff0c;简称 ASPP v2ASPP in DeepLab v3&#xff0c;简称 ASPP v3ASPP in DeepLab v3&#xff0c;简称 ASPP v3ASPP in MobileNet v3&am…...

anaconda创建虚拟环境在D盘

【看一看就行&#xff0c;又是挺水的一期&#xff08;每一季都掺和一点子水分也挺好&#xff09;】 一、创建&#xff1a; conda create --prefixD:\python37\py37 python3.7 这下就在D盘了&#xff1a; 二、激活刚刚那个环境&#xff1a; activate D:\pyhton37\py37​ &…...

Java设计模式之工厂设计模式

简介 工厂模式是一种常见的设计模式&#xff0c;用于创建对象的过程中&#xff0c;通过工厂类来封装对象的创建过程。其核心思想是将对象的创建和使用分离&#xff0c;从而降低耦合度&#xff0c;提高代码的可维护性和可扩展性。工厂模式通常包括三种类型&#xff1a;简单工厂…...

uniapp使用阿里图标

效果图&#xff1a; 前言 随着uniApp的深入人心&#xff0c;我司也陆续做了几个使用uniapp做的移动端跨平台软件&#xff0c;在学习使用的过程中深切的感受到了其功能强大和便捷&#xff0c;今日就如何在uniapp项目中使用阿里字体图标的问题为大家献上我的一点心得&#xff0…...

20230803激活手机realme GT Neo3

20230803激活手机realme GT Neo3 缘起&#xff1a; 新买的手机&#xff1a;realme GT Neo3 需要确认&#xff1a; 1、4K录像&#xff0c;时间不限制。 【以前的很多手机都是限制8/10/12/16分钟】 2、通话自动录音 3、定时开关机。 4、GPS记录轨迹不要拉直线&#xff1a;户外助…...

Spring Cloud Feign+Ribbon的超时机制

在一个项目中&#xff08;数据产品&#xff09;&#xff0c;需要对接企业微信中第三方应用。在使用 Feign 的去调用微服务的用户模块用微信的 code 获取 access_token 以及用户工厂信息时出现 Feign 重试超时报错的情况&#xff0c;通过此篇文章记录问题解决的过程。 一、问题重…...

使用docker 搭建nginx + tomcat 集群

创建3个Tomcat容器&#xff0c;端口分别映射到 8080,8081,8082&#xff0c;使用数据卷挂载&#xff0c;分别将宿主机目录下的 /opt/module/docker/tomcat3/ROOT1/&#xff0c;/opt/module/docker/tomcat3/ROOT2/&#xff0c;/opt/module/docker/tomcat3/ROOT2/ 挂载到 容器内部…...

从Spring的角度看Memcached和Redis及操作

目录 Memcached和Redis的区别 适用场景 Memcached配置使用 Redis配置使用 在SpringBoot的框架里&#xff0c;有直连Redis的SDK却没有Memcached的&#xff0c;可见相比地位。不过各有各的适应场景&#xff0c;Redis这个单线程模型确实非常强。 Memcached和Redis的区别 共同…...

【C语言学习】C语言的基础数据类型

一、数据类型 1.整型 short(短整型) int&#xff08;整型 long&#xff08;长整型&#xff09; long long&#xff08;长整型&#xff09;2.浮点型 float&#xff08;单精度型&#xff09; double&#xff08;双精度型&#xff09; long double3.字符类型 char…...

使用AIGC工具提升安全工作效率

新钛云服已累计为您分享760篇技术干货 在日常工作中&#xff0c;安全人员可能会涉及各种各样的安全任务&#xff0c;包括但不限于&#xff1a; 开发某些安全工具的插件&#xff0c;满足自己特定的安全需求&#xff1b;自定义github搜索工具&#xff0c;快速查找所需的安全资料、…...

HBase概述

HBase 一 HBase简介与环境部署 1.1 HBase简介&在Hadoop生态中的地位 1.1.1 什么是HBase HBase是一个分布式的、面向列的开源数据库HBase是Google BigTable的开源实现HBase不同于一般的关系数据库, 适合非结构化数据存储 1.1.2 BigTable BigTable是Google设计的分布式…...

el-popover全屏不显示(bug记录)

我做了一个el-table全屏展示的功能, 然后里面的el-popover在全屏后无法展示, 刚开始以为是写唯一的key或者ref, 发现写了也不行, 后来以为要写’:append-to-body“false”, 最后发现是我的外层的层级写得太高了; position: fixed; z-index: 9999; <div class"box"…...

react中使用redux-persist做持久化储存

某天下午折腾着玩的 – 笔记 安装相关依赖 npm install reduxjs/toolkit redux-persist redux react-redux// store.jsx import { configureStore, getDefaultMiddleware } from "reduxjs/toolkit"; import { persistStore, persistReducer } from "redux-per…...

【leetcode】203. 移除链表元素(easy)

给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* Lis…...

InfiniBand、UCIe相关思考

InfiniBand、UCIe相关思考 内容1、InfiniBandInfiniBand是什么&#xff1f;InfiniBand的来历是什么&#xff1f;InfiniBand为什么重要&#xff1f;InfiniBand相较于Ethernet区别&#xff1f;同领域内还有其他哪些技术&#xff1f;InfiniBand中RDMA是种什么技术&#xff1f; 内容…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...