猿问

基于线性时间中多个条件的切片中的广义计数元素

我需要以许多不同的方式在长数组中计算元素。


下面是特殊情况的用例示例:


func main() {

    test := []test{test{"A", "1", "$"}, test{"A", "2", "€"}, test{"B", "3", "$"}}


    countA := 0

    countDollar := 0

    countADollar := 0


    for _, e := range test {

        if e.prop1 == "A" {

            countA++

        }

        if e.prop3 == "$" {

            countDollar++

        }

        if e.prop1 == "A" && e.prop3 == "$" {

            countADollar++

        }

    }


    fmt.Printf("countA: %v, count$: %v, countA$: %v\n", countA, countDollar, countADollar)

}

这将打印


计数A: 2, 计数$: 2, 计数A$: 1


https://play.golang.org/p/R0nhwFpyN7H


现在的问题是:有没有办法对此进行泛化,以便我可以在数组的一次迭代中根据属性计算不同的总和,而无需单独实现每种情况?


编辑2:这是一个基于用户Volker建议的稍微好一点的版本:


package main


import "fmt"


type test struct {

    prop1 string

    prop2 string

    prop3 string

}


func count2(data []test, f func(test) bool) {

        count1 := 0;

    for _, e := range data {

        if f(e) {

            count1++

        }

    }

    fmt.Printf("count1: %v", count1)

}


func main() {

    data := []test{test{"A", "1", "$"}, test{"A", "2", "€"}, test{"B", "3", "$"}}

    

    myTestCrit := func(t test) bool {

        return t.prop1 == "A"

    }

    count2(data, myTestCrit)

}

https://play.golang.org/p/kB60gJCBkyn


编辑3:这是一个进一步的推广,接受多个计数器。感谢Volker和Eli的投入。也许这些来源对其他人也有用。


func count3(data []test, f []func(test) bool) {

        counts := make([]int, len(f));

    for _, e := range data {

        for i, fi := range f {

            if fi(e) {

                counts[i]++

            }

        }

    }

    fmt.Printf("counts: %v\n", counts)

}



func main() {

    data := []test{test{"A", "1", "$"}, test{"A", "2", "€"}, test{"B", "3", "$"}}

    

    myTestCrit := func(t test) bool {

        return t.prop1 == "A"

    }

    

    myTestCritDollar := func(t test) bool {

        return t.prop3 == "$"

    }

    

    

    countCrits := make([]func(t test) bool, 2)

    countCrits[0] = myTestCrit

    countCrits[1] = myTestCritDollar

    count3(data, countCrits)

}

编辑:我也愿意接受关于如何改进问题的建议。这是我遇到的一个合法问题,一般方法将大大简化我的代码。


三国纷争
浏览 92回答 1
1回答

ABOUTYOU

Go中没有特别的酱汁可以做到这一点。您需要在切片上编写一个循环 - 没关系。您的原始代码绝对没问题,特别是如果您需要在同一循环中执行多个不同的计数。该函数也很好,它抽象出一些代码(虽然不多),但它只对单个计数器有用 - 单个过滤器/测试函数。count2你可以继续推广它,例如,传入一个结构切片,其中每个结构都是:Metricstype Metrics struct {  Counter int  Filter func(test) bool}这完全取决于您的确切需求。如果你在这里寻找惯用的Go方式:不要太担心过早的抽象。编写最清晰/最易读的代码来解决眼前的任务。
随时随地看视频慕课网APP

相关分类

Go
我要回答