请求参数多键值对Dictionary按指定Key排序方法问询
如何生成指定键顺序的Dictionary参数请求
这个问题我之前对接API的时候也碰到过!普通字典本质是哈希结构,默认不会保留固定的键顺序,要实现你想要的指定顺序,得用对应语言的有序字典实现,或者手动按要求的顺序逐个插入键值对。下面分几种常见编程语言给你具体解决方案:
Python 实现
Python 3.7及以上版本的普通dict已经会严格保留插入顺序,所以我们只要按你想要的顺序逐个添加键值对就行。如果要兼容更早版本,可以用collections.OrderedDict。
场景1:保留mbappdetails嵌套结构,内部键按指定顺序
# 先定义你要的顺序 mbapp_inner_order = ["channelid", "appdtls", "devicedtls", "locationdtls"] top_level_order = ["mbappdetails", "token", "signcs"] # 你的原始数据 original_data = { "mbappdetails": { "locationdtls": {"ipAdress": "100.105.100.6", "locationDtl": "NaviMumbai,Maharashtra", "longdtl": "73.0152077", "latdtl": "19.1112212"}, "appdtls": {"appregflg": "00", "appid": "com.mmcompany.nstapp", "applversion": "1.0.70", "pushnkey": "cVCzsSyxCLr4l5JPElHWLDiNuoQJcbFmRlN5LFWZM9hN5lYYZnJy_4Kvvu2_fAjBXhGxbKpt"}, "devicedtls": {"deviceserial": "ExtEYNBSO8D85KR7DCEIOSHH", "devicemodel": "iPod Touch 6", "os": "iOS", "simflag": "N", "devicesdkversion": "12.10", "deviceproduct": "iPod Touch 6", "deviceid": "XXXXX-A2F5-XXXX-8EAC-XXXXX", "devicemake": "iPod touch", "rootflg": "N", "devicebrand": "APPLE", "osVersion": "12.1.4"}, "channelid": "XXXXXXRRRRRR" }, "token": "myToken", "signcs": "encrypted_dictionary_key_values_with_signature_key" } # 构造有序的mbappdetails子字典 ordered_mbapp = {key: original_data["mbappdetails"][key] for key in mbapp_inner_order} # 构造顶层有序字典 ordered_dict = { key: ordered_mbapp if key == "mbappdetails" else original_data[key] for key in top_level_order }
场景2:去掉mbappdetails嵌套,直接把四个键放到顶层
如果你需要的是顶层键为channelid,appdtls,devicedtls,locationdtls,token,signcs,可以这样做:
desired_order = ["channelid", "appdtls", "devicedtls", "locationdtls", "token", "signcs"] ordered_dict = {} # 先处理mbappdetails里的四个键 for key in desired_order[:4]: ordered_dict[key] = original_data["mbappdetails"][key] # 再处理顶层的token和signcs for key in desired_order[4:]: ordered_dict[key] = original_data[key]
Java 实现
Java的HashMap是无序的,要实现有序字典,用LinkedHashMap就可以了——它会严格保留插入顺序。
import java.util.LinkedHashMap; import java.util.Map; public class OrderedParamRequest { public static void main(String[] args) { // 先构造各个子参数字典 Map<String, String> locationdtls = new LinkedHashMap<>(); locationdtls.put("ipAdress", "100.105.100.6"); locationdtls.put("locationDtl", "NaviMumbai,Maharashtra"); locationdtls.put("longdtl", "73.0152077"); locationdtls.put("latdtl", "19.1112212"); Map<String, String> appdtls = new LinkedHashMap<>(); appdtls.put("appregflg", "00"); appdtls.put("appid", "com.mmcompany.nstapp"); appdtls.put("applversion", "1.0.70"); appdtls.put("pushnkey", "cVCzsSyxCLr4l5JPElHWLDiNuoQJcbFmRlN5LFWZM9hN5lYYZnJy_4Kvvu2_fAjBXhGxbKpt"); Map<String, String> devicedtls = new LinkedHashMap<>(); devicedtls.put("deviceserial", "ExtEYNBSO8D85KR7DCEIOSHH"); devicedtls.put("devicemodel", "iPod Touch 6"); devicedtls.put("os", "iOS"); devicedtls.put("simflag", "N"); devicedtls.put("devicesdkversion", "12.10"); devicedtls.put("deviceproduct", "iPod Touch 6"); devicedtls.put("deviceid", "XXXXX-A2F5-XXXX-8EAC-XXXXX"); devicedtls.put("devicemake", "iPod touch"); devicedtls.put("rootflg", "N"); devicedtls.put("devicebrand", "APPLE"); devicedtls.put("osVersion", "12.1.4"); // 构造有序的mbappdetails Map<String, Object> mbappdetails = new LinkedHashMap<>(); mbappdetails.put("channelid", "XXXXXXRRRRRR"); mbappdetails.put("appdtls", appdtls); mbappdetails.put("devicedtls", devicedtls); mbappdetails.put("locationdtls", locationdtls); // 构造顶层有序字典 Map<String, Object> orderedDict = new LinkedHashMap<>(); orderedDict.put("mbappdetails", mbappdetails); orderedDict.put("token", "myToken"); orderedDict.put("signcs", "encrypted_dictionary_key_values_with_signature_key"); // 如果要去掉嵌套,直接这样写: // Map<String, Object> orderedDict = new LinkedHashMap<>(); // orderedDict.put("channelid", "XXXXXXRRRRRR"); // orderedDict.put("appdtls", appdtls); // orderedDict.put("devicedtls", devicedtls); // orderedDict.put("locationdtls", locationdtls); // orderedDict.put("token", "myToken"); // orderedDict.put("signcs", "encrypted_dictionary_key_values_with_signature_key"); } }
C# 实现
C#的Dictionary<TKey, TValue>是无序的,要实现指定顺序的字典,可以用OrderedDictionary(保留插入顺序)。
using System.Collections.Specialized; using System.Collections.Generic; class OrderedParamRequest { static void Main() { // 构造子参数字典 Dictionary<string, string> locationdtls = new Dictionary<string, string> { {"ipAdress", "100.105.100.6"}, {"locationDtl", "NaviMumbai,Maharashtra"}, {"longdtl", "73.0152077"}, {"latdtl", "19.1112212"} }; Dictionary<string, string> appdtls = new Dictionary<string, string> { {"appregflg", "00"}, {"appid", "com.mmcompany.nstapp"}, {"applversion", "1.0.70"}, {"pushnkey", "cVCzsSyxCLr4l5JPElHWLDiNuoQJcbFmRlN5LFWZM9hN5lYYZnJy_4Kvvu2_fAjBXhGxbKpt"} }; Dictionary<string, string> devicedtls = new Dictionary<string, string> { {"deviceserial", "ExtEYNBSO8D85KR7DCEIOSHH"}, {"devicemodel", "iPod Touch 6"}, {"os", "iOS"}, {"simflag", "N"}, {"devicesdkversion", "12.10"}, {"deviceproduct", "iPod Touch 6"}, {"deviceid", "XXXXX-A2F5-XXXX-8EAC-XXXXX"}, {"devicemake", "iPod touch"}, {"rootflg", "N"}, {"devicebrand", "APPLE"}, {"osVersion", "12.1.4"} }; // 构造有序的mbappdetails OrderedDictionary mbappdetails = new OrderedDictionary(); mbappdetails.Add("channelid", "XXXXXXRRRRRR"); mbappdetails.Add("appdtls", appdtls); mbappdetails.Add("devicedtls", devicedtls); mbappdetails.Add("locationdtls", locationdtls); // 构造顶层有序字典 OrderedDictionary orderedDict = new OrderedDictionary(); orderedDict.Add("mbappdetails", mbappdetails); orderedDict.Add("token", "myToken"); orderedDict.Add("signcs", "encrypted_dictionary_key_values_with_signature_key"); // 去掉嵌套的写法: // OrderedDictionary orderedDict = new OrderedDictionary(); // orderedDict.Add("channelid", "XXXXXXRRRRRR"); // orderedDict.Add("appdtls", appdtls); // orderedDict.Add("devicedtls", devicedtls); // orderedDict.Add("locationdtls", locationdtls); // orderedDict.Add("token", "myToken"); // orderedDict.Add("signcs", "encrypted_dictionary_key_values_with_signature_key"); } }
小提醒
如果你的最终目的是生成HTTP请求参数(比如JSON或表单),一定要确认你的请求客户端是否会保留字典的顺序——有些客户端会自动对键进行排序,这时候可能需要直接构造字符串形式的参数,避免被客户端篡改顺序。
内容的提问来源于stack exchange,提问作者user10959828
相关产品推荐
相关产品推荐

