2014-12-03 100 views
0

我有客户与API交互的日志文件。我想分析这些日志并将结果提供给结构图,以便将数据组织成有用的信息。例如,我想回应以下查询:“显示每个用户每天的请求总数”。golang:我如何在循环中填充多结构映射?

我已经创建了一个看起来像保存数据的适当结构。但是,当我尝试运行该程序时,出现错误: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++ 
    } 
} 

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

+0

......你没有访问该领域的。注意,在你的代码中除了结构体定义之外,你都可以输入'listOfDates'或'listOfCustomers'。你需要导出它们并访问它们。 – 2014-12-03 22:10:57

+0

@SimonWhitehead我不确定你的意思。导出如何帮助我在循环中填充多结构映射? – SunSparc 2014-12-03 22:28:08

+0

...你不是试图填充地图..多数民众赞成我的观点。你正在索引你的“日期”和“客户”类型..这是不可能的。为了说明我的意思......将'日期[fields [1]] ...'改为'dates.ListOfDates [fields [1]] ...'。这应该让你的问题显而易见。 – 2014-12-03 22:29:43

回答

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}