golang:如何在循环中填充多结构图?

时间:2014-12-03 22:06:54

标签: go

我有客户与API交互的日志文件。我想解析这些日志并将结果提供到结构图中,以便我可以将数据组织成有用的信息。例如,我想回复以下问题:“向我显示每个用户每天的请求总数”。

我已经创建了一个看似合适的结构来保存数据。但是,当我尝试运行程序时,我收到错误:invalid operation: dates[fields[1]] (type *Dates does not support indexing) [process exited with non-zero status]

http://play.golang.org/p/8u3jX26ktt

package main

import (
    "fmt"
    "strings"
)

type Stats struct {
    totalNumberOfRequests int
}
type Customer struct {
    listOfCustomers map[string]Stats // map[customerid]Stats
}
type Dates struct {
    listOfDates map[string]Customer // map[date]Customer
}

var requestLog = []string{
    "2011-10-05, 1234, apiquery",
    "2011-10-06, 1234, apiquery",
    "2011-10-06, 5678, apiquery",
    "2011-10-09, 1234, apiquery",
    "2011-10-12, 1234, apiquery",
    "2011-10-13, 1234, apiquery",
}

func main() {
    dates := new(Dates)
    for _, entry := range requestLog {
        fmt.Println("entry:", entry)
        fields := strings.Split(entry, "'")
        dates.listOfDates[fields[0]].listOfCustomers[fields[1]].totalNumberOfRequests++
    }
}

是否有更好的结构使用?或者有没有办法让这个结构适合这个特定目的?

1 个答案:

答案 0 :(得分:1)

如果我理解您对输出的期望,这是一个解决方案。但是我不喜欢“客户是带有id和Stat的地图..我认为它应该是一个带有两个字段(cid stringstat Stats)的更简单的结构。此外,日期结构不允许对于同一天的多个客户,我已将其更改为将单个日期映射到用户列表。

我还添加了更多“测试场景”,以涵盖客户在同一天多次访问资源的情况。

您似乎没有使用“apiquery”您的示例,因此下面的代码与它不匹配。

关于结构中指针的更改 - 请参阅this issue(如您问题的评论中所述)

package main

import (
    "fmt"
    "strings"
)

type Stats struct {
    totalNumberOfRequests int
}
type Customer struct {
    customerWithStat map[string]*Stats // a customer with it's corresponding stats
}

type Dates struct {
    listOfDates map[string][]*Customer // map[date]list of customers (for each date)
}

var requestLog = []string{
    "2011-10-05, 1234, apiquery",
    "2011-10-06, 5678, apiquery",
    "2011-10-06, 1234, apiquery",
    "2011-10-06, 1234, apiquery",
    "2011-10-06, 5678, apiquery",
    "2011-10-06, 1234, apiquery",
    "2011-10-09, 1234, apiquery",
    "2011-10-12, 1234, apiquery",
    "2011-10-13, 1234, apiquery",
    "2011-10-13, 1234, apiquery",
    "2011-10-06, 1234, apiquery",
}

func main() {
    listOfDates := make(map[string][]*Customer)
    dates := Dates{listOfDates}
    for _, entry := range requestLog {
        fields := strings.Split(entry, ",")
        curDateStr := strings.TrimSpace(fields[0])
        curCustIdStr := strings.TrimSpace(fields[1])

        if customersAtDate, dateExists := dates.listOfDates[curDateStr]; dateExists {
            // Date already exist
            for _, curCustomer := range customersAtDate {
                if curStat, customerExists := curCustomer.customerWithStat[curCustIdStr]; customerExists {
                    // The user has already accessed this resource - just increment
                    curStat.totalNumberOfRequests++
                } else {
                    // New user - set access to 1
                    curCustomer.customerWithStat[curCustIdStr] = &Stats{1}
                }
            }
        } else {
            // New Date

            // Init the Statistic for the new customer
            newCustomerData := make(map[string]*Stats)
            newCustomerData[curCustIdStr] = &Stats{1}

            // Create the customer itself
            newCustomer := &Customer{newCustomerData}

            // add to the current day list
            dates.listOfDates[curDateStr] = append(dates.listOfDates[curDateStr], newCustomer)

        }
    }

    // Print result
    for date, customers := range dates.listOfDates {
        fmt.Println("Date: ", date)
        for _, customer := range customers {
            for cid, stat := range customer.customerWithStat {
                fmt.Println("  Customer: ", cid)
                fmt.Println("  # Requests: ", *stat)
            }
        }
    }
}

这将输出:

Date:  2011-10-05
  Customer:  1234
  # Requests:  {1}
Date:  2011-10-06
  Customer:  5678
  # Requests:  {2}
  Customer:  1234
  # Requests:  {4}
Date:  2011-10-09
  Customer:  1234
  # Requests:  {1}
Date:  2011-10-12
  Customer:  1234
  # Requests:  {1}
Date:  2011-10-13
  Customer:  1234
  # Requests:  {2}