Краткий Golang способ поиска ключевого свойства в срезе объекта - PullRequest
4 голосов
/ 21 января 2020

Я создал 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
}

Я вызываю их в al oop в 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)
    }
}

Свойства структур: Role.Name, SuperWorkflow.Workflow.Name и Permission.URN являются string уникальными ключами.
Существует ли краткий способ в Golang, используя указатель функции или что-то подобное, использовать только одну функцию вместо 3 containsRole(), containsWorkflow() а containsPermission() и уменьшить дублирование?

1 Ответ

5 голосов
/ 21 января 2020

Это самые чистые и эффективные решения до появления дженериков.

Свойства структур: Role.Name, SuperWorkflow.Workflow.Name и Permission.URN являются string уникальными ключами.

Вы можете сортировать фрагменты по уникальному ключу, чтобы вы могли использовать бинарный поиск при поиске элемента, см. sort.Search().

Также вы можете хранить их в карте, сопоставленной с уникальным ключом, и операция contains становится простой индексацией карты, например, !containsRole() будет иметь вид:

if _, ok := roles[x]; !ok {
    // there is no role with Name == x
}

Этот поиск карты будет более быстрым по сравнению с вашим последовательным Алгоритм поиска, и, скорее всего, он также превзойдет бинарный поиск.

(Конечно, вам не нужно добавлять для него функцию, просто индексируйте карту, чтобы узнать, содержится ли x в она.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...