使用Go在一片结构中按时间平均

时间:2013-09-02 14:20:50

标签: go

我在一个基本方式的片段中按小时平均值,我会得到一个更好的方法,以获得一个最通用的功能,可以按小时,天,周等平均。提前感谢大家。

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:我在考虑数据已经分类了 操场: http://play.golang.org/p/lL3YDD4ecE

2 个答案:

答案 0 :(得分:2)

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

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

中的完整代码

答案 1 :(得分: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成组,你可以总结,平均等等。