Go语言 如何跳过切片中的值,如果它第一次匹配条件

m1m5dgzv  于 2023-09-28  发布在  Go
关注(0)|答案(4)|浏览(94)

如果条件匹配一次,如何跳过切片中的值。

func main() {

    cloud := []string{"moon", "earth", "moon-light"}

    for _, value := range cloud {

        if strings.Contains(value, "mo") {
            fmt.Println("print1")
        } else if strings.Contains(value, "ear") {
            fmt.Println("print2")
        }
    }
}

输出:print 1 print 2 print 1
预期输出:打印1打印2
谢谢!

41zrol4v

41zrol4v1#

您可以使用Map来了解是否发生了某种情况。它比使用变量更好,因为它允许您跟踪大量条件而不会造成任何混乱。下面是您所需示例:

cloud := []string{"moon", "earth", "moon-light"}
var conditionTracker = make(map[string]bool)

for _, value := range cloud {

    if _, ok := conditionTracker["first_condition"]; !ok && strings.Contains(value, "mo") {
        conditionTracker["first_condition"] = true
        fmt.Println("print1")
    } else if _, ok := conditionTracker["second_condition"]; !ok && strings.Contains(value, "ear") {
        conditionTracker["second_condition"] = true
        fmt.Println("print2")
    }
}
qgzx9mmu

qgzx9mmu2#

如果您想根据已经满足的条件跳过切片中的某些值,则可以使用flag变量来跟踪它。要获得所需的输出,可以按如下方式修改代码:

package main

import (
    "fmt"
    "strings"
)

func main() {
    cloud := []string{"moon", "earth", "moon-light"}
    conditionMet := false // Initialize a flag variable

    for _, value := range cloud {
        if conditionMet {
            // If the condition has already been met, skip further processing
            continue
        }

        if strings.Contains(value, "mo") {
            fmt.Println("print1")
            conditionMet = true // Set the flag to true once the condition is met
        } else if strings.Contains(value, "ear") {
            fmt.Println("print2")
        }
    }
}

在这段代码中,我们引入了conditionMet变量,它以false开头。当满足“mo”条件时,我们打印“print1”并将conditionMet设置为true。循环的后续迭代将检查conditionMet是否为真,如果是,则它们将跳过进一步的处理,导致预期的输出“print1 print2”。
这种方法可以确保“mo”条件只匹配一次。

imzjd6km

imzjd6km3#

package main

import (
    "fmt"
    "strings"
)

func main() {
    cloud := []string{"moon", "earth", "moon-light"}

    print1Flag := false
    print2Flag := false

    for _, value := range cloud {
        if strings.Contains(value, "mo") && !print1Flag {
            fmt.Println("print1")
            print1Flag = true
        } else if strings.Contains(value, "ear") && !print2Flag {
            fmt.Println("print2")
            print2Flag = true
        }
    }
}

代码检查标志变量print1Flagprint2Flag,以确保每个条件只打印一次。输出将为:

print1
print2
uinbv5nw

uinbv5nw4#

其他答案为您的特定示例提供了基本机制,一般情况下的解决方案可以使用包含标识要匹配的模式的键的Map,并且每个键的值是所需的结果/输出。
一旦你匹配了一个键,就从Map中删除它,这样它就不会被第二次匹配:

cloud := []string{"moon", "earth", "moon-light"}
    match := map[string]string{
        "mo": "print1",
        "ear": "print2",
    }

    for _, value := range cloud {
        for k, v := range match {
            if strings.Contains(value, k) {
                fmt.Println(v)
                delete(find, k)
            }
        }
    }

这可能效率较低(至少对于较大的切片和/或Map),因为它涉及两个范围循环,但如果效率/可扩展性比可重用性更重要,则可以通过将代码放入函数中来执行任何一次性匹配:

func find(s []string, m map[string]string) (result []string) {
    for _, c := range s {
        for k, v := range m {
            if strings.Contains(c, k) {
                result = append(result, v)
                delete(m, k)
            }
        }
    }
    return result
}

func main() {
    cloud := []string{"moon", "earth", "moon-light"}
    match := map[string]string{"mo": "print1", "ear": "print2"}

    for _, r := range find(cloud, match) {
        fmt.Println(r)
    }
}

Playground here
(我不确定'find'是否是这样一个函数的最佳名称,因为这更像是一个转换而不是查找;一个更好的名字在你的具体用例我留给你:))
通过一个小的修改,find函数可以成为一个过滤器,返回满足匹配Map(不再需要是Map,可以是子字符串匹配的简单切片)的切片中的那些条目。所以,如果你有一些处理要对匹配的条目执行,而不仅仅是转换它们/输出一些字符串,你会首先过滤然后迭代返回的切片:

func filter(s []string, m []string) (result []string) {
    for _, c := range s {
        for i, v := range m {
            if strings.Contains(c, v) {
                result = append(result, c)
                m = append(m[:i], m[i+1:]...)
            }
        }
    }
    return result
}

func main() {
    cloud := []string{"moon", "earth", "moon-light"}
    match := []string{"mo", "ear"}

    for _, r := range filter(cloud, match) {
        fmt.Println(r)
    }
}

请注意,从切片中删除项目比从Map中删除项目要麻烦一些。
Playground here.

相关问题