Go 基于线性时间多准则的切片广义计数元素

Go 基于线性时间多准则的切片广义计数元素,go,Go,我需要在长数组中以多种不同的方式计算元素 下面是一个特殊情况的用例示例: func main() { test := []test{test{"A", "1", "$"}, test{"A", "2", "€"}, test{"B", "3", "$"}} countA := 0 countD

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

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

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)
}
这会打印出来

countA:2,count$:2,countA$:1

现在的问题是:有没有一种方法可以将其推广,这样我就可以在数组的一次迭代中根据属性计算不同的和,而不必分别实现每种情况


编辑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)
}


编辑3:这里是接受多个计数器的进一步推广。感谢沃尔克和伊莱的投入。也许这些资料对其他人也会有用

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)
}


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

要做到这一点,Go中没有特别的调味品。您需要在片上写一个循环-没关系

您的原始代码非常好,特别是当您需要在同一个循环中执行几个不同的计数时。
count2
函数也很好,它提取了一点代码(虽然不多),但它只对单个计数器有用-单个过滤器/测试函数

您可以通过以下方式对其进行概括,例如,传入一片
度量
结构,其中每个结构都是:

type Metrics struct {
  Counter int
  Filter func(test) bool
}
这完全取决于你的确切需要


如果您正在寻找惯用的方式,请点击这里:不要过于担心过早抽象。编写最清晰/可读性最强的代码来解决眼前的任务。

不,没有语言结构,但是如果您使用
func(test)bool
作为属性,您可以传递一组属性并对每个属性进行计数,然后返回计数列表。@Volker是的,可以,我会发布一个editOK,我会这样做的,因为你有这么多的业力,也许你可以给我一个提示,这个问题出了什么问题?@初学者:很抱歉,你的经历不好。我没有否决你的问题,也没有投票结束它,但我尽了最大努力提供了一个答案:)所以我不认为它有什么问题,尽管显然有些人这样认为。也许他们会插嘴。是的,很公平。如果没有什么明显的问题,那也没关系,只是不想做任何冒犯社区的事。