2014-12-03 33 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}