在对象切片内搜索关键属性的简洁 Golang 方式

Sha*_*ail 4 function-pointers function functor go slice

我创建了 3 个搜索功能:

func containsRole(x string, a []Role) bool {
    for _, n := range a {
        if x == n.Name {
            return true
        }
    }
    return false
}
func containsWorkflow(x string, a []SuperWorkflow) bool {
    for _, n := range a {
        if x == n.Workflow.Name {
            return true
        }
    }
    return false
}
func containsPermission(x string, a []Permission) bool {
    for _, n := range a {
        if x == n.URN {
            return true
        }
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)

我在其他 3 个不同的函数中循环调用它们,例如:

// In function 1
for _, leftRole := range leftRoles {
    if !containsRole(leftRole.Name, rightRoles) {
        createRoleReport(leftRole))
    }
}
// In function 2
for _, leftWF := range leftWorkflows {
    if !containsWorkflow(leftWF.Workflow.Name, rightWorkflows) {
        createWorkflowReport(leftWF)
    }
}
// In function 3
for _, leftPerm := range leftPermissions {
    if !containsPermission(leftPerm.URN, rightPermissions) {
        createPermissionReport(leftPerm)
    }
}
Run Code Online (Sandbox Code Playgroud)

结构性能:Role.NameSuperWorkflow.Workflow.Name并且Permission.URNstring唯一键。
在 Golang 中是否有一种简洁的方法,使用函数指针之类的,只使用一个函数而不是 3 containsRole(), containsWorkflow(), andcontainsPermission()并减少重复?

icz*_*cza 5

在泛型出现之前,这些是最干净、最有效的解决方案。

结构性能:Role.NameSuperWorkflow.Workflow.Name并且Permission.URNstring唯一键。

您可以按唯一键对切片进行排序,因此您可以在查找元素时使用二分搜索,请参阅sort.Search()

您也可以将它们存储在映射中,从唯一键映射,并且contains操作变成一个简单的映射索引,例如!containsRole()

if _, ok := roles[x]; !ok {
    // there is no role with Name == x
}
Run Code Online (Sandbox Code Playgroud)

与您的顺序搜索算法相比,这种地图查找的速度会更快,并且很可能也会击败二分搜索。

(当然,您不必为它添加函数,只需索引地图,您需要知道其中是否x包含它。)