Golang中如何按原顺序从map提取键值

Golang中如何按原顺序从map提取键值 如何获取与“map[string]interface{}”类型映射中存储顺序相同的键? 我尝试过 reflect 包中的 MapKeys() 方法,也尝试过使用“for 循环”来提取,但都无法获得与映射中现有顺序相同的键。 请帮我解决这个问题。

谢谢

5 回复

并非总是按照映射中存在的相同顺序获取键。

更多关于Golang中如何按原顺序从map提取键值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


map 是无序的。如果你想要这种有序行为,就需要自己实现一个类型。

只需创建一个切片,并在 for/range 循环中添加键。例如

package main
import "fmt"

func main() {
m := map[string]int{
	"rsc": 3711,
	"r":   2138,
	"gri": 1908,
	"adg": 912,
}

keys := make([]string, 0, len(m))
for k := range m {
	keys = append(keys, k)
}
fmt.Println(keys)
}

有一些库实现了有序映射。例如:

GitHub GitHub

头像

elliotchance/orderedmap

🔃 Go语言中的有序映射,其Set、Get、Delete和Len操作均摊时间复杂度为O(1)。 - elliotchance/orderedmap

在Go语言中,map的键值顺序是随机的,这是语言设计上的特性,无法保证与插入顺序一致。如果你需要保持键的顺序,可以使用以下两种方法:

方法一:使用切片维护顺序

创建一个切片来存储键的顺序,然后按这个顺序访问map。

package main

import "fmt"

func main() {
    data := map[string]interface{}{
        "name":  "John",
        "age":   30,
        "city":  "New York",
        "email": "john@example.com",
    }

    // 定义键的顺序
    keys := []string{"name", "age", "city", "email"}

    // 按顺序访问map
    for _, key := range keys {
        if value, exists := data[key]; exists {
            fmt.Printf("%s: %v\n", key, value)
        }
    }
}

方法二:使用有序map结构

如果需要动态维护顺序,可以创建一个结构体来组合map和切片。

package main

import "fmt"

type OrderedMap struct {
    keys   []string
    values map[string]interface{}
}

func NewOrderedMap() *OrderedMap {
    return &OrderedMap{
        keys:   make([]string, 0),
        values: make(map[string]interface{}),
    }
}

func (om *OrderedMap) Set(key string, value interface{}) {
    if _, exists := om.values[key]; !exists {
        om.keys = append(om.keys, key)
    }
    om.values[key] = value
}

func (om *OrderedMap) Get(key string) (interface{}, bool) {
    val, exists := om.values[key]
    return val, exists
}

func (om *OrderedMap) Keys() []string {
    return om.keys
}

func main() {
    om := NewOrderedMap()
    om.Set("name", "John")
    om.Set("age", 30)
    om.Set("city", "New York")
    om.Set("email", "john@example.com")

    // 按插入顺序获取键
    for _, key := range om.Keys() {
        value, _ := om.Get(key)
        fmt.Printf("%s: %v\n", key, value)
    }
}

方法三:使用第三方库

如果你不想自己实现,可以使用第三方库如github.com/elliotchance/orderedmap

package main

import (
    "fmt"
    "github.com/elliotchance/orderedmap"
)

func main() {
    om := orderedmap.NewOrderedMap()
    om.Set("name", "John")
    om.Set("age", 30)
    om.Set("city", "New York")
    om.Set("email", "john@example.com")

    // 按顺序遍历
    for el := om.Front(); el != nil; el = el.Next() {
        fmt.Printf("%s: %v\n", el.Key, el.Value)
    }
}

这些方法可以确保你按照需要的顺序访问map中的键值对。

回到顶部