1

我以一种基本的方式在一片结构中按小时对值进行平均,我会得到更好的方法来获得一个可以按小时、天、周等平均的最通用的函数。提前致谢致所有人。

package main

import (
    "fmt"
    "math/rand"
    "time"
)

type Acc struct {
    name  string
    money int
    date time.Time
}

type Accs []Acc

const Tformat = "02/01/2006 15:04:05"

func main() {
    var myaccs Accs
    acc := 0
    var loops int
    var hour int
    f1, _ := time.Parse(Tformat, "29/08/2013 00:00:19")
    // Creating a Slice of structs 
    for i := 0; i < 10; i++ { 
        f1 = f1.Add(20 * time.Minute) //adding 20 minutes to every record
        myaccs = append(myaccs, Acc{name: "christian", money: rand.Intn(200), date: f1})
        fmt.Printf("Added to slice: %v, %d, %s\n", myaccs[i].name, myaccs[i].money, myaccs[i].date)
    }
    // Averaging 
    for _, v := range myaccs {
        if acc == 0 {
            hour = v.date.Hour()
            acc += v.money
            loops++
        } else {
            if v.date.Hour() == hour {
                acc += v.money
                loops++
            } else {
                fmt.Printf("Average money value to hour %d : %d\n", hour, acc / loops) //->Action

                acc = v.money
                hour = v.date.Hour()
                loops = 1
            }
        }
        //fmt.Println(v, acc, loops, hour)
    }
    fmt.Printf("Average money value to hour %d : %d\n", hour, acc / loops)//->Action
}

注意:Money 变量是一个 int,仅作为示例。
注 2:我正在考虑数据已经排序
Playground: http ://play.golang.org/p/lL3YDD4ecE

4

2 回答 2

2

时间数学充满了危险,但这是解决问题的一种方法:

type Snapshot struct {
    Value AccountValue
    At    time.Time
}

type Granularity struct {
    Name          string
    DateIncrement [3]int
    DurIncrement  time.Duration
    DateFormat    string
}

type Graph struct {
    Granularity
    Values map[string][]AccountValue
}

func (g *Graph) Add(snaps []Snapshot) {
    if g.Values == nil {
        g.Values = map[string][]AccountValue{}
    }
    for _, s := range snaps {
        key := g.Format(s.At)
        g.Values[key] = append(g.Values[key], s.Value)
    }
}

func (g *Graph) Get(from, to time.Time) (snaps []Snapshot) {
    from, to = g.Truncate(from), g.Truncate(to)
    for cur := from; !to.Before(cur); cur = g.AddTo(cur) {
        var avg, denom AccountValue
        for _, v := range g.Values[g.Format(cur)] {
            avg += v
            denom += 1
        }
        if denom > 0 {
            avg /= denom
        }
        snaps = append(snaps, Snapshot{
            Value: avg,
            At:    cur,
        })
    }
    return snaps
}

Playground中的完整代码

于 2013-09-02T18:21:00.727 回答
1

对于未排序的数据

首先在 Accs []Acc 类型上实现排序接口。然后,您可以轻松地按小时、天、周排序。

对于排序数据

在 Accs 上创建 GroupBy 方法。

func (accs Accs) GroupBy(p func(Acc,Acc) bool) [][]Accs {
    // your looping/comparing/grouping code goes here
}

使用谓词函数 p 传入特定于组的代码,以比较两个 Acc 结构,以查看它们是否应该进入同一组。

一旦 Accs 分组,您就可以求和、平均等。

于 2013-09-02T15:29:20.397 回答