如何在Go语言中对map[string]interface{}类型进行多重排序?

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

How to multiple sort a map[string]interface{} type in go lang?

问题

场景:假设我有一个要在Go语言中处理的JSON数据。现在我正在使用encoding/json包中的map[string]interface{}类型,通过执行marshal/unmarshal操作。

以下是JSON数据:

{
    "MysoreCity": {
        "Population": 1000,
        "VehicleCount": 1700,
        "Temperature": 33
    },
    "BangaloreCity": {
        "Population": 1000,
        "VehicleCount": 3500,
        "Temperature": 33
    },
    "KolarCity": {
        "Population": 1250,
        "VehicleCount": 3500,
        "Temperature": 31
    },
    "TumkurCity": {
        "Population": 800,
        "VehicleCount": 300,
        "Temperature": 29
    }
}

现在我想根据优先级进行多重降序排序,例如优先级为TemperaturePopulationVehicleCount,然后我希望输出结果如下:

{
    "BangaloreCity": {
        "Population": 1000,
        "VehicleCount": 3500,
        "Temperature": 33
    },
    "MysoreCity": {
        "Population": 1000,
        "VehicleCount": 1700,
        "Temperature": 33
    },
    "KolarCity": {
        "Population": 1250,
        "VehicleCount": 3500,
        "Temperature": 31
    },
    "TumkurCity": {
        "Population": 800,
        "VehicleCount": 300,
        "Temperature": 29
    }
}

因此,根据一组动态优先级进行排序。

问题:我不知道如何在Go语言中进行此类排序。我是Go语言的新手,在搜索排序数据时找到了一些信息;其中提到如下内容(来源:链接
>>使用range循环迭代映射时,迭代顺序未指定,并且不能保证从一次迭代到下一次迭代的顺序相同。

问题:有人能够解释一下如何对类似的JSON数据进行这种排序吗?

英文:

Scenario: Consider I have a JSON data to be processed in go lang
Now I am using map[string]interface{} type using package encoding/json by doing marshal/unmarshal

Below is the JSON data:

{
    "MysoreCity": {
        "Population": 1000,
        "VehicleCount": 1700,
        "Temperature": 33
    },
    "BangaloreCity": {
        "Population": 1000,
        "VehicleCount": 3500,
        "Temperature": 33
    },
    "KolarCity": {
        "Population": 1250,
        "VehicleCount": 3500,
        "Temperature": 31
    },
    "TumkurCity": {
        "Population": 800,
        "VehicleCount": 300,
        "Temperature": 29
    }
}

Now I want to perform a multi-sort descending order on the basis of priority, say priority is Temperature, Population, VehicleCount then I want the output to be like

{
    "BangaloreCity": {
        "Population": 1000,
        "VehicleCount": 3500,
        "Temperature": 33
    },
    "MysoreCity": {
        "Population": 1000,
        "VehicleCount": 1700,
        "Temperature": 33
    },
    "KolarCity": {
        "Population": 1250,
        "VehicleCount": 3500,
        "Temperature": 31
    },
    "TumkurCity": {
        "Population": 800,
        "VehicleCount": 300,
        "Temperature": 29
    }
}

So the sorting with respect to some dynamic set of priorities.

Issue: I am not getting any clues how to sort it in go lang. I am new to go lang and found something while searching for sorting my data; where it is mentioned as below (source:link)
>>When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next.

Question: Could anyone put some light on how to do this kind of sorting with similar JSON data?

答案1

得分: 0

我已经为您翻译了代码部分,如下所示:

// 从N个地图中获取一个结果地图和排序后的键
func getSortedKeys(maps ...map[string]string) (map[string]string, []string) {
	var keys []string
	resultMap := map[string]string{}

	for _, currMap := range maps {
		for k, v := range currMap {
			resultMap[k] = v
			keys = append(keys, k)
		}
	}
	sort.Strings(keys)
	return resultMap, keys
}

// 在函数外部可以这样使用:
concatenedMaps, keys := getSortedKeys(map1, map2)
for _, k := range keys {
	value := concatenedMaps[k]
}

希望对您有帮助!如果您有任何其他问题,请随时提问。

英文:

I did this function get a result map from N maps and its sorted keys.

func getSortedKeys(maps ...map[string]string) (map[string]string, []string) {
	var keys []string
	resultMap := map[string]string{}

	for _, currMap := range maps {
		for k, v := range currMap {
			resultMap[k] = v
			keys = append(keys, k)
		}
	}
	sort.Strings(keys)
	return resultMap, keys

}

Outside the function you can do:

  concatenedMaps, keys := getSortedKeys(map1,map2)
  for _, k := range keys {
		value := concatenedMaps[k]
  }

答案2

得分: 0

这个答案更多地关于解决这个问题的方法论,而不是具体的解决方案。我认为这是你目前需要的,因为你离一个实际的解决方案还很远。以下是简单的步骤:

1)为此定义一个类型,我将在这里称之为City

"TumkurCity": {
    "Population": 800,
    "VehicleCount": 300,
    "Temperature": 29
}

type City struct {
    Population   int
    VehicleCount int
    Temperature  int
    Name         string
}

2)将其解组为map[string]City

3)使用以下方法转换数据;

func ToSlice(m map[string]City) []City {
    cities := make([]City, 0, len(m))
    for k, v := range m {
        v.Name = k
        cities = append(cities, v)
    }
    return cities
}

4)定义一些方法来按照你想要的方式对城市进行排序

我在浏览器中编写了这段代码,所以它还没有经过测试。它应该提供了一个足够的示例来处理它。当你解组时,City类型的name字段将没有值,所以你可以稍后将键(城市的名称)赋给它。将它们放入一个切片或数组中,对其进行排序。如果按照这些步骤进行操作,就很简单。

英文:

This answer is more about the methodology for solving this problem than a specific solution. I think it's more what you need at this point because you're not close to an actual solution. Here are the simple procedural steps;

  1. define a type for this, I'll call it City from here on;

    "TumkurCity": {
    "Population": 800,
    "VehicleCount": 300,
    "Temperature": 29
    }

    type City struct {
    Population int
    VehicleCount int
    Temperature int
    Name string
    }

  2. unmarshal into a map[string]City

  3. use a method like this to transform the data;

    func ToSlice(m map[string]City) []City {
    cities := make([]City, 0, len(m))
    for k, v := range m {
    v.Name = k
    cities = append(cities, v)
    }
    return cities
    }

  4. define some method to sort the cities however it is you want

I wrote that code in the browser so it hasn't been tested or anything. It should provide a sufficient example of how to handle it. When you unmarshal your City types will have no value for name so you can just assign the key (the cities name) to that later on. put them in a slice or array, sort that. Pretty simple if you follow those steps.

答案3

得分: 0

你可以使用https://github.com/rxwycdh/rxhash中的rxhash.SortMap函数,可以按键对嵌套的复杂映射进行排序。

例如:

import "github.com/rxwycdh/rxhash"

dd := map[string]any{
	"MysoreCity": map[string]any{
		"Population":   1000,
		"VehicleCount": 1700,
		"Temperature":  33,
	},
	"BangaloreCity": map[string]any{
		"Population":   1000,
		"VehicleCount": 3500,
		"Temperature":  33,
	},
	"KolarCity": map[string]any{
		"Population":   1250,
		"VehicleCount": 3500,
		"Temperature":  31,
	},
	"TumkurCity": map[string]any{
		"Population":   800,
		"VehicleCount": 300,
		"Temperature":  29,
	},
}

b, _ := json.Marshal(rxhash.SortMap(dd))
println(string(b))

输出结果:

{
    "BangaloreCity": {
        "Population": 1000,
        "Temperature": 33,
        "VehicleCount": 3500
    },
    "KolarCity": {
        "Population": 1250,
        "Temperature": 31,
        "VehicleCount": 3500
    },
    "MysoreCity": {
        "Population": 1000,
        "Temperature": 33,
        "VehicleCount": 1700
    },
    "TumkurCity": {
        "Population": 800,
        "Temperature": 29,
        "VehicleCount": 300
    }
}
英文:

you can use https://github.com/rxwycdh/rxhash rxhash.SortMap, can sort nested complex map by key.

for example:

import "github.com/rxwycdh/rxhash"

dd := map[string]any{
	"MysoreCity": map[string]any{
		"Population":   1000,
		"VehicleCount": 1700,
		"Temperature":  33,
	},
	"BangaloreCity": map[string]any{
		"Population":   1000,
		"VehicleCount": 3500,
		"Temperature":  33,
	},
	"KolarCity": map[string]any{
		"Population":   1250,
		"VehicleCount": 3500,
		"Temperature":  31,
	},
	"TumkurCity": map[string]any{
		"Population":   800,
		"VehicleCount": 300,
		"Temperature":  29,
	},
}

b, _ := json.Marshal(rxhash.SortMap(dd))
println(string(b))

output:

{
    "BangaloreCity": {
        "Population": 1000,
        "Temperature": 33,
        "VehicleCount": 3500
    },
    "KolarCity": {
        "Population": 1250,
        "Temperature": 31,
        "VehicleCount": 3500
    },
    "MysoreCity": {
        "Population": 1000,
        "Temperature": 33,
        "VehicleCount": 1700
    },
    "TumkurCity": {
        "Population": 800,
        "Temperature": 29,
        "VehicleCount": 300
    }
}

答案4

得分: 0

你可以尝试对其进行排序。请参考以下示例代码:

func sortCollection(data map[string]interface{}, f string) map[string]interface{} {
    var col []int
    for _, d := range data {
        if val := d.(map[string]interface{}); len(val) > 0 {
            col = append(col, val[f].(int))
        }
    }
    sort.Ints(col)
    resMap := map[string]interface{}{}
    for _, s := range col {
        for k, d := range data {
            if val := d.(map[string]interface{}); len(val) > 0 {
                if _, ok := resMap[k]; !ok {
                    if s == val[f].(int) {
                        resMap[k] = d
                        break
                    }
                }
            }
        }
    }
    return resMap
}

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

英文:

You can try to sort it. Please see sample code in go dev

func sortCollection(data map[string]interface{}, f string) map[string]interface{} {
var col []int
for _, d := range data {
	if val := d.(map[string]interface{}); len(val) > 0 {
		col = append(col, val[f].(int))
	}
}
sort.Ints(col)
resMap := map[string]interface{}{}
for _, s := range col {
	for k, d := range data {
		if val := d.(map[string]interface{}); len(val) > 0 {
			if _, ok := resMap[k]; !ok {
				if s == val[f].(int) {
					resMap[k] = d
					break
				}
			}
		}
	}
}
return resMap
}

huangapple
  • 本文由 发表于 2015年4月9日 18:44:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/29536345.html
匿名

发表评论

匿名网友

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

确定