【问题标题】:Sorting a Map of Structs - GOLANG对结构图进行排序 - GOLANG
【发布时间】:2013-11-25 15:41:07
【问题描述】:

我有一个结构映射,我通过将数据流式传输到 Go 程序来填充这些结构。更新地图的方式类似于下面的示例。

一旦我填充了这个结构映射,按照结构中count 字段的值对该映射进行排序的最佳(或好)方法是什么?

package main

type data struct {
    count int64
}

func main() {
    m := make(map[string]data)
    m["x"] = data{0, 0}
    if xx, ok := m["x"]; ok {
        xx.count = 2
        m["x"] = xx
    } else {
        panic("X isn't in the map")
    }
}

这个例子可以在这里运行:http://play.golang.org/p/OawL6QIXuO

【问题讨论】:

  • 您可能需要考虑使用 B-Tree 或红黑树来实现您的目的。据我所知,Go 库中没有参考实现,但这些数据结构无论如何也不难实现。

标签: sorting map struct go


【解决方案1】:

正如 siritinga 已经指出的那样,map 的元素没有排序,因此您无法对其进行排序。

您可以做的是创建一个slice 并使用sort 包对元素进行排序:

package main

import (
    "fmt"
    "sort"
)

type dataSlice []*data

type data struct {
    count int64
    size  int64
}

// Len is part of sort.Interface.
func (d dataSlice) Len() int {
    return len(d)
}

// Swap is part of sort.Interface.
func (d dataSlice) Swap(i, j int) {
    d[i], d[j] = d[j], d[i]
}

// Less is part of sort.Interface. We use count as the value to sort by
func (d dataSlice) Less(i, j int) bool {
    return d[i].count < d[j].count
}

func main() {
    m := map[string]*data {
        "x": {0, 0},
        "y": {2, 9},
        "z": {1, 7},
    }

    s := make(dataSlice, 0, len(m))

    for _, d := range m {
        s = append(s, d)
    }       

    // We just add 3 to one of our structs
    d := m["x"]
    d.count += 3

    sort.Sort(s)

    for _, d := range s {
        fmt.Printf("%+v\n", *d)
    }
}

输出:

{计数:1 尺寸:7}
{计数:2 尺寸:9}
{计数:3 大小:0}

Playground

编辑

更新了示例以使用指针并包含一个映射,以便您既可以进行查找又可以对切片进行排序。

【讨论】:

  • 我想使用地图的原因是我将通过程序流式传输数百万条记录,并在处理数据时更新每个键的计数。填充映射并将其转换为结构切片是否有意义?结构中的字段只是映射中的键和计数。
  • @DJElbow 有一个带有指向您的结构的指针的映射来进行查找以添加计数,同时维护一个带有指向相同结构的指针的切片是有意义的。因此,切片和映射在结构的相同实例上工作。
  • @siritinga Yepp,我看到了 :) 但我有一些空闲时间,所以我想我可以把你的评论变成一个实际的例子。
  • @siritinga 我不确定 DJElbow 的意思是“唯一记录”,只是计数的总和将是数百万。但我同意,如果会有数百万条唯一记录,您建议的解决方案(堆)或 FUZxxl 的建议(B-tree 或红黑树)可能是更好的选择。
  • @DJElbow 通常从一个简单的解决方案开始并在需要时进行优化。如果回答解决了您的问题,请记住标记为已接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-23
  • 2017-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多