草庐IT

戈朗 : How can I populate a multi-struct map in a loop?

coder 2024-07-08 原文

我有客户与 API 交互的日志文件。我想解析这些日志并将结果提供给结构映射,以便我可以将数据组织成有用的信息。例如,我想响应以下查询:“显示每个用户每天的请求总数”。

我已经创建了一个看起来足够的结构来保存数据。但是,当我尝试运行程序时出现错误:无效操作:dates[fields[1]](type *Dates 不支持索引)[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++
    }
}

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

最佳答案

如果我理解您对输出的期望,这里有一个解决方案。但是我不喜欢“Customer is a map with id and Stat.. I think it should be a simple struct with two Fields (cid string and stat 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}

关于戈朗 : How can I populate a multi-struct map in a loop?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27282602/

有关戈朗 : How can I populate a multi-struct map in a loop?的更多相关文章

  1. 戈朗 "Log in to the site and download the xls file"? - 2

    关闭。这个问题需要更多focused.它目前不接受答案。想改进这个问题吗?更新问题,使其只关注一个问题editingthispost.关闭3年前。Improvethisquestion告诉我如何使用Golang登录网站。下载xls文件是得到了,但是为了在Excel表格中有数据,需要登录网站。该站点位于公司的服务器上。如果你能告诉你怎么做。例如,我用来执行此操作的VBA代码。SetoFields=CreateObject("Scripting.Dictionary")WithoFields.Add"login","sdiscor".Add"password","sdiscor"EndWi

  2. arrays - 戈朗 : Could not understand how below code is executing - 2

    下面是我查询的代码:我有一个单维数组a当我打印a[0][0]时,我不明白为什么它返回字符a的ascii值:packagemainimport("fmt")funcmain(){a:=[3]string{"a","b","c"}fmt.Println(a[0][0])}输出:97 最佳答案 下面是如何打印ascii的代码示例a:=[3]string{"a","b","c"}for_,rune:=rangea{fmt.Println(rune)//Itwillprinta,b,c}因为你在你的代码中使用了[0][0],所以它是等价的fo

  3. 戈朗 :which way is more efficient about using "for range" - 2

    typepath[]bytefunc(ppath)ToUpper(){fori,b:=rangep{if'a'在上面(这个例子是从“TheGoBlog”复制过来的),如果ToUpper变成这样:func(ppath)ToUpper(){fori,_:=rangep{if'a'哪个会更有效率为什么?“TheGoBlog”对前一个说:“这里的ToUpper方法在forrange构造中使用两个变量来捕获索引和slice元素。这种形式的循环避免了在主体中多次写入p[i]。”什么意思? 最佳答案 前者有更多的内存操作,即在b上:它在循环的第一

  4. 戈朗 : go command inside script? - 2

    我有一个用Golang编写的脚本,我不太明白。我想知道他为什么要在脚本里面写goserver.Start()?为什么不简单地编写server.Start?packagemainimport("github.com/miekg/dns""testing""time")constTEST_ADDR="127.0.0.1:9953"funcTestDNSResponse(t*testing.T){server:=NewDNSServer(&Config{dnsAddr:TEST_ADDR,})goserver.Start()//Allowsometimeforservertostarttim

  5. 戈朗 : Is there a way to modify one of the multi-value return parameters in one line? - 2

    我正在尝试在Go中做一些相对简单的事情——将字符串转换为整数,然后将其加倍:myInt,_:=strconv.Atoi(args[1])doubleArg:=myInt*2由于Atoi()返回两个参数(整数和err),我使用myInt,_:=来检索值的整数。我想将它加倍(因此是第二行)但不能在一行中完成所有操作:myInt,_:=strconv.Atoi(args[1])*2给我:multiple-valuestrconv.Atoi()insingle-valuecontext但是,根据我使用大多数其他语言的经验,必须在两行中执行此操作似乎有很多样板。这只是我必须处理的一个限制,还是有

  6. elasticsearch - 戈朗错误 "not enough arguments in call" - 2

    我刚接触golang。尝试通过golang实现批量上传到Elasticsearch。我正在使用golang库->https://github.com/olivere/elastic用于与Elasticsearch通信。此外,我正在尝试一段示例代码,但出现以下错误...suresh@BLR-245:~/Desktop/tools/golang/src$goinstallgithub.com/crazyheart/elastic-bulk-upload#github.com/crazyheart/elastic-bulk-uploadgithub.com/crazyheart/elasti

  7. multithreading - 戈朗 : can WaitGroup leak with go-routines - 2

    我计划实现一个go-routine并有一个sync.WaitGroup同步创建的go-routine的结尾。我基本上使用go创建了一个线程.所以它是这样的:main(){varwgsync.WaitGroupfor{gomyThread(wg)wg.Add(1)}wg.wait()}myThread(wgsync.WaitGroup){deferwg.Done()}我之前曾与pthread_create合作过在某些情况下确实无法创建线程。在这种情况下,是否可能针对上述gomyThread(wg)无法启动和/或运行wg.Done()例程的其余部分是否正常运行?如果是这样,将报告什么以及如

  8. 戈朗 : appending slices with or w/o allocation - 2

    Go的append()函数仅在给定slice的容量不足时分配新的slice数据(另请参见:https://stackoverflow.com/a/28143457/802833)。这可能会导致意外行为(至少对我这个golang新手来说):packagemainimport("fmt")funcmain(){a1:=make([][]int,3)a2:=make([][]int,3)b:=[][]int{{1,1,1},{2,2,2},{3,3,3}}common1:=make([]int,0)common2:=make([]int,0,12)//providesufficientcap

  9. xml - 戈朗 : Compare XML structures - 2

    我需要编写一个测试来验证服务器响应。响应必须包含某些header和xml正文。首先,如何检查响应中是否存在所需的header。以及如何比较收到的XML和所需的XML。例如。响应必须包含header“Serv”。正文必须包含对象为“person”的xmlHTTP/1.1200OKConnection:Keep-AliveServ:"any-string"Content-Length:0Content-Type:text/xml;charset=UTF-8string-value我如何检查响应是否包含标题“Serv”并包含带有元素人和名称的正文xml 最佳答案

  10. arrays - 戈朗 : Is this an acceptable way to create a Slice from part of another Slice? - 2

    我四处搜索并没有找到另一个这样做的例子,但我无意中发现我能够通过简单地将另一个slice的片段传递给接受slice并返回它的函数来从另一个slice的片段创建一个sliceslice。例子:packagemainimport"fmt"funcmakeSliceFrom(s[]int)[]int{returns}funcmain(){s:=[]int{1,2,3,4,5,6,7,8,9,10}newS:=makeSliceFrom(s[1:7])fmt.Println(newS)}我不是在问这是否有效,因为我知道它有效并且似乎运作良好,我是在问这是否得到支持或有一些我不知道的不可预见的成

随机推荐