对于Golang,如何对二维结构体数组进行排序?

huangapple go评论82阅读模式
英文:

Sort 2D array of structs Golang

问题

我想为一个二维结构体切片创建一个一致的排序,我是从一个映射中创建这个二维切片,所以顺序总是不同的。

我的结构体如下:

// Hit 包含了一个命中的数据。
type Hit struct {
	Key  string  `json:"key"`
	Data []Field `json:"data"`
}

// Hits 存储了一系列的命中。
type Hits [][]Hit

我想为Hits类型的内容提供一个一致的顺序。

我尝试过:

func (c Hits) Len() int { return len(c) }

func (c Hits) Swap(i, j int) { c[i], c[j] = c[j], c[i] }

func (c Hits) Less(i, j int) bool { return strings.Compare(c[i][0].Key, c[j][0].Key) == -1 }

但结果似乎仍然以随机顺序返回。

我在考虑可能对切片中的每个项进行哈希处理,但想知道是否有更简单的选项。

英文:

I want to create a consistent ordering for a 2D slice of structs, I am creating the 2D slice from a map so the order is always different.

My structs look like

// Hit contains the data for a hit.
type Hit struct {
	Key  string  `json:"key"`
	Data []Field `json:"data"`
}

// Hits stores a list of hits.
type Hits [][]Hit

I want to provide a consistent order for the contents of my Hits type.

I have tried:


func (c Hits) Len() int { return len(c) }


func (c Hits) Swap(i, j int) { c[i], c[j] = c[j], c[i] }


func (c Hits) Less(i, j int) bool { return strings.Compare(c[i][0].Key, c[j][0].Key) == -1 }

But the results still seem to come back in random order.

I was thinking of possibly hashing each item in the slice but thought there might be an easier option

答案1

得分: 1

map的迭代顺序是不确定的,因为它是一个哈希表(实际上并不是这样——将具有相同键的项按照相同的顺序插入到两个映射中,它们的迭代顺序将是相同的)。

假设你的映射是map[string]Hit,为了以确定的顺序迭代它,我会枚举映射中的键集,对其进行排序,然后使用排序后的集合来枚举映射。

类似这样的代码:

package main

import (
  "fmt"
  "sort"
)

type Hit struct {
  Key  string  `json:"key"`
  Data []Field `json:"data"`
}

type Field struct {
  Value string `json:"value"`
}

func main() {
  var mapOfHits = getSomeHits()
  var sortedHits = sortHits(mapOfHits)
  
  for _, h := range sortedHits {
    fmt.Println(h.Key)
  }

}

func getSomeHits() map[string]Hit {
  return make(map[string]Hit, 0)
}

func sortHits(m map[string]Hit) []Hit {
  keys := make([]string, 0, len(m))
  sorted := make([]Hit, 0, len(m))
  
  for k := range m {
    keys = append(keys, k)
  }

  sort.Strings(keys)

  for _, k := range keys {
    sorted = append(sorted, m[k])
  }

  return sorted
}

你可以点击这里查看示例代码。

英文:

The order of iteration over a map, because it's a hash table is rather indeterminate (it's not, really — insert items with the same keys in the same exact sequence into 2 maps and the order of iteration for each will be identical).

Assuming that your map is a map[string]Hit, to iterate it over in a determinate order, I would enumerate the set of keys in the map, sort that, and use that sorted set to enumerate the map.

Something like this:

package main

import (
  "fmt"
  "sort"
)

type Hit struct {
  Key  string  `json:"key"`
  Data []Field `json:"data"`
}

type Field struct {
  Value string `json:"value"`
}

func main() {
  var mapOfHits = getSomeHits()
  var sortedHits = sortHits(mapOfHits)
  
  for _, h := range sortedHits {
    fmt.Println(h.Key)
  }

}

func getSomeHits() map[string]Hit {
  return make(map[string]Hit, 0)
}

func sortHits(m map[string]Hit) []Hit {
  keys := make([]string, 0, len(m))
  sorted := make([]Hit, 0, len(m))
  
  for k := range m {
    keys = append(keys, k)
  }

  sort.Strings(keys)

  for _, k := range keys {
    sorted = append(sorted, m[k])
  }

  return sorted
}

huangapple
  • 本文由 发表于 2022年5月13日 01:24:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/72219821.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定