I created 3 search functions:
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
}
I'm calling them in a loop in 3 other different functions like:
// 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)
}
}
The properties of structs: Role.Name
, SuperWorkflow.Workflow.Name
and Permission.URN
are string
unique keys.
Is there a concise way in Golang, using function pointer or something, to use only one function instead of 3 containsRole()
, containsWorkflow()
, and containsPermission()
and reduce duplication?
Those are the cleanest and most efficient solutions until generics arrive.
The properties of structs:
Role.Name
,SuperWorkflow.Workflow.Name
andPermission.URN
arestring
unique keys.
You could sort the slices by the unique key, so you could use binary search when looking for an element, see sort.Search()
.
Also you could store them in a map, mapped from the unique key, and the contains
operation becomes a simple map indexing, e.g. !containsRole()
would be:
if _, ok := roles[x]; !ok {
// there is no role with Name == x
}
This map lookup will be superior in speed compared to your sequential search algorithm, and will most likely beat the binary search too.
(You wouldn't have to add a function for it of course, just index the map where you need to know if x
is contained in it.)