Javascript 递归地排序对象和嵌套对象以及数组
Javascript recursively order object and nested objects as well as arrays
我正在尝试获得与pythons json.dumps()相同的结果,并启用了按键排序。这是作为预请求脚本预先形成的,供 Postman 生成请求哈希。输出需要排序为有效的 json,用作哈希的输入。我是javascript的新手,看到许多旧的答案声称javascript中的对象无法排序。但是,必须有一个解决方案来生成给定条件的哈希值。
- 无法更改对象结构。
- 它只需要支持Chrome。
- 我可以使用库。
- requestParams 可以包含需要以任何深度排序的嵌套对象和数组。
这是我当前的代码。在 Chrome 控制台中,sortedResult 的对象预览是未排序的,但是当我展开对象和子对象时,Chrome 控制台将 sortedResult 显示为已排序,完全符合应有的方式。这给我的印象是排序对象正在工作。但是,requestOrdered 返回有效的 json 对象,但它不会排序。我最初的想法是,也许JSON.stringify()正在对它进行排序。
const requestRebuilt = {"username": user, "password": password, "sTime": time, "function": function,
"functionParams": requestParams, "salt": salt};
function sortObject(object){
var keys = _.keys(object);
var sortedKeys = _.sortBy(keys, function(key){
//console.log(key);
return key;
});
var sortedObj = {};
var sortedObjJson = "";
for(var index in keys){
var key = keys[index];
//console.log(key + ' ' + typeof object[key]);
if(typeof object[key] == 'object' && !(object[key] instanceof Array)){
sortedObj[key] = sortObject(object[key]);
} else if(object[key] instanceof Array) {
//sortedObj[key] = object[key].sort();
var arrayLength = object[key].length;
for (var i = 0; i < arrayLength; i++) {
sortedObj[key] = sortObject(object[key][i]);
//console.log(object[key][i]);
}
} else {
sortedObj[key] = object[key];
}
}
return sortedObj;
}
const sortedResult = sortObject(requestRebuilt);
console.log(sortedResult);
const requestOrdered = JSON.stringify(sortedResult);
console.log(requestOrdered);
var hash = CryptoJS.SHA256(requestOrdered).toString();
postman.setGlobalVariable("hash", hash);
示例输入:
{
"username": "jdoe@mail.com",
"sTime": "2016-03-04T13:53:37Z",
"function": "begin",
"functionParams": {
"tip": "ABC123FFG",
"pad": 4 ,
"passenger": [{
"firstName": "John",
"phone": 1234567890,
"email": "jdoe@mail.com",
"dateOfBirth": "1915-10-02T00:00:00Z",
"bans": {
"weight": 9,
"count": 2
}
}
]},
"salt": "00d878f5e203",
"pep": "sdeODQ0T"
}
在python中,这是通过以下方法完成的:
ordered = json.dumps(
{"username": user, "password": password, "time": time, "function": function, "functionParams": functionParams, "salt": salt}
sort_keys=True, separators=(',', ':'))
订购结果:
{"function":"begin","functionParams":{"passenger":[{"bans":{"count":2,"weight":9},"dateOfBirth":"1915-10-02T00:00:00Z","email":"jdoe@mail.com","firstName":"John","phone":1234567890}],"pad":4,"tip":"ABC123FFG"},"pep":"sdeODQ0T","salt":"00d878f5e203","sTime":"2016-03-04T13:53:37Z","username":"jdoe@mail.com"}
打印精美,便于阅读,但实际结果不应有空格或新行:
{
"function": "begin",
"functionParams": {
"passenger": [
{
"bans": {
"count": 2,
"weight": 9
},
"dateOfBirth": "1915-10-02T00:00:00Z",
"email": "jdoe@mail.com",
"firstName": "John",
"phone": 1234567890
}
],
"pad": 4,
"tip": "ABC123FFG"
},
"pep": "sdeODQ0T",
"salt": "00d878f5e203",
"sTime": "2016-03-04T13:53:37Z",
"username": "jdoe@mail.com"
}
在javascript中"对象键没有排序"是一个常见的误解。MDN 指出
尽管 ECMAScript 使对象的迭代顺序依赖于实现,但似乎所有主流浏览器都支持基于最早添加的属性的迭代顺序(至少对于不在原型上的属性)。
ES2015 使此行为成为标准:
对于每个自己的属性键 P 的 O 是一个字符串,但不是整数索引,按属性创建顺序...
也就是说,您可以依赖这样一个事实,即对象属性始终按广告顺序迭代(除非您使用的是 delete
,有关详细信息,请参阅此处)。
因此,要对某个对象中的键进行排序,只需创建一个新对象并按排序顺序向其添加键:
function sortKeys(x) {
if (typeof x !== 'object' || !x)
return x;
if (Array.isArray(x))
return x.map(sortKeys);
return Object.keys(x).sort().reduce((o, k) => ({...o, [k]: sortKeys(x[k])}), {});
}
////
obj = {
"username": "jdoe@mail.com",
"sTime": "2016-03-04T13:53:37Z",
"function": "begin",
"functionParams": {
"tip": "ABC123FFG",
"pad": 4,
"passenger": [{
"firstName": "John",
"phone": 1234567890,
"email": "jdoe@mail.com",
"dateOfBirth": "1915-10-02T00:00:00Z",
"bans": {
"weight": 9,
"count": 2
}
}
]
},
"salt": "00d878f5e203",
"pep": "sdeODQ0T"
}
sorted = sortKeys(obj);
console.log(sorted);
- Javascript(Angular)从一个对象数组到第二个数组查找值
- 在Javascript中转换对象数组
- 在JavaScript中通过索引从对象数组中获取值
- Backbone虹吸以获取对象数组
- 如何在DataTables 2.1中迭代对象数组
- Javascript-根据赋值顺序,按键合并对象数组
- 将事件附加到对象/数组
- jQuery$.inArray()总是返回-1和一个对象数组
- javascript处理一个对象数组以获得一个新的对象数组
- javascript在数组中获取对象数组中键的所有不同值
- 在对象数组中查找多个值的d3范围
- Undercore.js获取对象数组中键对象的值
- 在mongoose中使用正则表达式在对象数组中进行查询搜索
- 如何通过json对象数组为嵌套对象赋值
- 如何循环通过2个对象数组并通过匹配id进行合并
- 为对象数组创建列表项
- 如何使用javascript合并两个对象数组
- JSON到对象数组,并向每个对象添加项
- JavaScript:从对象数组中获取唯一值及其计数
- 按不同项目对对象数组进行排序