首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将map[string]int分割成块

如何将map[string]int分割成块
EN

Stack Overflow用户
提问于 2019-09-10 13:01:51
回答 1查看 2.2K关注 0票数 2

我的目标是获取一个可能包含多达100万个条目的map[string]int,并将其块大小高达500个,并将地图发布到外部服务。我是哥朗的新成员,所以我现在正在围棋操场上修修补补。

任何关于如何提高我的代码库效率的技巧,请分享!

操场:Pd9X91c

我看到的CLI输出是:

代码语言:javascript
复制
original size 60
chunk bookends 0 20
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
chunk bookends 20 40
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
chunk bookends 40 60
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,

这里的问题是,在正确计算块书签结束的同时,每次x值从0开始。我想我应该期望它从块的最小书签开始,这将是0,20,40等等。,为什么范围每次从0开始?

来源:

代码语言:javascript
复制
package main

import (
    "fmt"
    "math/rand"
    "strconv"
)

func main() {
    items := make(map[string]int)

    // Generate some fake data for our testing, in reality this could be 1m entries
    for i := 0; i < 60; i ++ {
        // int as strings are intentional here
        items[strconv.FormatInt(int64(rand.Int()), 10)] = rand.Int()
    }

    // Create a map of just keys so we can easily chunk based on the numeric keys
    i := 0
    keys := make([]string, len(items))
    for k := range items {
            keys[i] = k
            i++
    }

    fmt.Println("original size", len(keys))
    //batchContents := make(map[string]int)

    // Iterate numbers in the size batch we're looking for
    chunkSize := 20
    for chunkStart := 0; chunkStart < len(keys); chunkStart += chunkSize {
        chunkEnd := chunkStart + chunkSize

        if chunkEnd > len(items) {  
            chunkEnd = len(items)
        }

        // Iterate over the keys
        fmt.Println("chunk bookends", chunkStart, chunkEnd)
        for x := range keys[chunkStart:chunkEnd] {
            fmt.Print(x, ",")

            // Build the batch contents with the contents needed from items
            // @todo is there a more efficient approach?
            //batchContents[keys[i]] = items[keys[i]]
        }
        fmt.Println()

        // @todo POST final batch contents
        //fmt.Println(batchContents)
    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-10 13:05:04

当您处理一个块时:

代码语言:javascript
复制
for x := range keys[chunkStart:chunkEnd] {}

您正在对一个片进行迭代,并且有一个迭代变量,它将是片索引,而不是片中的元素(在给定的索引处)。因此,它总是从0开始。(在映射上迭代时,第一个迭代变量是键,因为那里没有索引,第二个迭代变量是与该键关联的值。)

相反,你想要这个:

代码语言:javascript
复制
for _, key := range keys[chunkStart:chunkEnd] {}

还请注意,首先在片中收集密钥,然后处理它们是多余的。首先,当迭代映射一次时,您可以这样做。只需保持一个变量计数迭代,以知道何时到达块大小,如果您使用数据结构来保持这一点(例如,密钥批处理片的大小),这可能是隐式的。

例如(在围棋游乐场上尝试):

代码语言:javascript
复制
chunkSize := 20
batchKeys := make([]string, 0, chunkSize)
process := func() {
    fmt.Println("Batch keys:", batchKeys)
    batchKeys = batchKeys[:0]
}

for k := range items {
    batchKeys = append(batchKeys, k)
    if len(batchKeys) == chunkSize {
        process()
    }
}
// Process last, potentially incomplete batch
if len(batchKeys) > 0 {
    process()
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57871411

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档