热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在Go中实现切片或结构映射的通用过滤器

我有多个带有“DateLastModified”字段的结构,如下所示:typeThingstruct{DateLastModifiedtime

我有多个带有“DateLastModified”字段的结构,如下所示:

type Thing struct {
DateLastModified time.Time
...
}
type Thing2 struct {
DateLastModified time.Time
...
}

我有每个这些结构的切片或映射:

things := []Thing{...}
thing2s := []Thing2{...}
//or
things := make(map[string]Thing)
thing2s := make(map[string]Thing2)

我想要做的是过滤他们DateLastModified领域中的每个切片或地图。

这很容易以基本方式实现,但我有兴趣了解更多关于 Go 的知识。

我想知道的是:有没有办法以我可以执行以下操作的方式实现该过滤器:

filteredThings := filterSliceOnTime(things, someTimeToFilterOn)
filtered2Things := filterSliceOnTime(thing2s, someTimeToFilterOn)
//or
filteredThings := filterMapOnTime(things, someTimeToFilterOn)
filtered2Things := filterMapOnTime(thing2s, someTimeToFilterOn)

我想弄清楚的是如何减少冗余代码,因为所有这些结构都具有 DateLastModified 字段。

谢谢!

回答

Go 没有协方差的概念,因此filterXOnTime将无法对不同底层结构的切片[]V或映射进行操作。map[K]VV

带接口

您可以做的是声明一个I公开公共行为的接口,并让两个结构都实现该接口:

type Modifiable interface {
GetDateLastModified() time.Time
}
type Thing struct {
DateLastModified time.Time
...
}
func (t Thing) GetDateLastModified() time.Time {
return t.DateLastModified
}
type Thing2 struct {
DateLastModified time.Time
...
}
func (t Thing2) GetDateLastModified() time.Time {
return t.DateLastModified
}

此时,您可以拥有 的切片和映射I,并且您的过滤器功能可以与这些一起工作(接受和返回):

func filterSliceOnTime(modifiables []Modifiable, someTimeToFilterOn time.Time) []Modifiable {
var filtered []Modifiable
for _, m := range modifiables {
if m.GetDateLastModified.After(someTimeToFilterOn) {
filtered = append(filtered, m)
}
}
return filtered
}

这种方法的有效性受到以下事实的限制:为了使用“通用”函数,您必须重新映射[]ThingX[]Modifiable,反之亦然。

带有辅助函数

为了减轻上述解决方案的维护麻烦,您可以改用一个对单个项目进行操作的辅助过滤器功能,这样您就不必来回映射复杂类型:

func checkOne(v Modifiable, filterOn time.Time) bool {
return v.GetDateLastModified().After(filterOn)
}
func main() {
a := make(map[string]Thing, 0)
a["foo"] = Thing{time.Now()}
filtered := make(map[string]Thing, 0)
for k, v := range a {
if checkOne(v, time.Now().Add(-2*time.Hour)) {
filtered[k] = v
}
} fmt.Println(filtered) // map[foo:{blah}]
}

Go 1.18 并输入参数

随着 Go 1.18(2022 年初)和泛型的引入,您将能够直接使用切片和映射。您仍然需要声明接口来为类型参数提供适当的约束,并且结构仍然必须实现它。

使用当前的草稿设计,可能看起来像:

func filterSliceOnTime[T Modifiable](s []T, filterOn time.Time) []T {
var filtered []T
for _, v := range s {
if v.GetDateLastModified().After(filterOn) {
filtered = append(filtered, v)
}
}
return filtered
}

Go2 游乐场:https ://go2goplay.golang.org/p/FELhv0NSr5A






推荐阅读
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 设计模式——模板方法模式的应用和优缺点
    本文介绍了设计模式中的模板方法模式,包括其定义、应用、优点、缺点和使用场景。模板方法模式是一种基于继承的代码复用技术,通过将复杂流程的实现步骤封装在基本方法中,并在抽象父类中定义模板方法的执行次序,子类可以覆盖某些步骤,实现相同的算法框架的不同功能。该模式在软件开发中具有广泛的应用价值。 ... [详细]
  • 本文介绍了在go语言中利用(*interface{})(nil)传递参数类型的原理及应用。通过分析Martini框架中的injector类型的声明,解释了values映射表的作用以及parent Injector的含义。同时,讨论了该技术在实际开发中的应用场景。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
author-avatar
mobiledu2502913567
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有