例如以下
var data = {
'States': ['NSW', 'VIC'],
'Countries': ['GBR', 'AUS'],
'Capitals': ['SYD', 'MEL']
}
for (var item in data) {
console.log(item);
}
打印
States
Countries
Capitals
有没有办法按字母顺序排序以便打印
Capitals
Countries
States
不在对象本身内:对象的属性集合是无序的。
您可以做的一件事是使用
Object.keys()
,对数组进行排序,然后迭代它。
Object.keys(data)
.sort()
.forEach(function(v, i) {
console.log(v, data[v]);
});
针对不支持 ECMAScript 第五版的浏览器的补丁(实现):
这是一个很好的功能解决方案:
基本上,
Object.keys
sort
按键ES5 解决方案:
not_sorted = {b: false, a: true};
sorted = Object.keys(not_sorted)
.sort()
.reduce(function (acc, key) {
acc[key] = not_sorted[key];
return acc;
}, {});
console.log(sorted) //{a: true, b: false}
ES6 解决方案:
not_sorted = {b: false, a: true}
sorted = Object.keys(not_sorted)
.sort()
.reduce((acc, key) => ({
...acc, [key]: not_sorted[key]
}), {})
console.log(sorted) //{a: true, b: false}
你也可以这样排序。
const data = {
States: ['NSW', 'VIC'],
Countries: ['GBR', 'AUS'],
Capitals: ['SYD', 'MEL']
}
const sortedObject = Object.fromEntries(Object.entries(data).sort())
我无法详细解释它为什么有效,但显然它工作得完美:)如果你不相信我,请自己尝试一下:D
请注意,您的浏览器或 Node.js 版本应支持
Object.fromEntries
有关浏览器兼容性,请检查本页底部
对于 Node,它将适用于 12 及更高版本。 对于 v1 中的 Deno。
是的,有。 不符合 ECMAScript 标准,但跨浏览器和 Node.js 支持,而且显然很稳定。 请参阅https://stackoverflow.com/a/23202095/645715。
EDIT:这将返回一个对象,其中键已排序。 您可以使用
Object.keys(...)
从对象中获取有序键。
为什么要担心对象键顺序?这种差异在某些应用程序中可能很重要,例如使用 xml2js 解析 XML,它将 XML 表示为嵌套对象,并使用 XML 标签作为哈希键。
有几个注意事项:
Object.keys(obj)
for (var key in obj) {...}
报告的顺序在 Safari、Firefox 中可能有所不同该函数返回一个对象,其中按字母顺序插入排序键:
function orderKeys(obj) {
var keys = Object.keys(obj).sort(function keyOrder(k1, k2) {
if (k1 < k2) return -1;
else if (k1 > k2) return +1;
else return 0;
});
var i, after = {};
for (i = 0; i < keys.length; i++) {
after[keys[i]] = obj[keys[i]];
delete obj[keys[i]];
}
for (i = 0; i < keys.length; i++) {
obj[keys[i]] = after[keys[i]];
}
return obj;
}
这是一个快速测试:
var example = {
"3": "charlie",
"p:style": "c",
"berries": "e",
"p:nvSpPr": "a",
"p:txBody": "d",
"apples": "e",
"5": "eagle",
"p:spPr": "b"
}
var obj = orderKeys(example);
这回来了
{ '3': 'charlie',
'5': 'eagle',
apples: 'e',
berries: 'e',
'p:nvSpPr': 'a',
'p:spPr': 'b',
'p:style': 'c',
'p:txBody': 'd' }
然后您可以获得订购的密钥:
Object.keys(obj)
哪个回报
["3", "5", "apples", "berries", "p:nvSpPr", "p:spPr", "p:style", "p:txBody"]
我会将此作为评论添加到 @prototype 的帖子中,但我的代表不够高。
如果有人需要
@prototype 编写的
orderKeys
兼容 eslint-config-airbnb
的版本:
/**
* Returns and modifies the input object so that its keys are returned in sorted
* order when `Object.keys(obj)` is invoked
*
* @param {object} obj The object to have its keys sorted
*
* @returns {object} The inputted object with its keys in sorted order
*/
const orderKeys = (obj) => {
// Complying with `no-param-reassign`, and JavaScript seems to assign by reference here
const newObj = obj;
// Default `.sort()` chained method seems to work for me
const keys = Object.keys(newObj).sort();
const after = {};
// Add keys to `after` in sorted order of `obj`'s keys
keys.forEach((key) => {
after[key] = newObj[key];
delete newObj[key];
});
// Add keys back to `obj` in sorted order
keys.forEach((key) => {
newObj[key] = after[key];
});
return newObj;
};
使用
@prototype的测试:
const example = {
3: 'charlie',
'p:style': 'c',
berries: 'e',
'p:nvSpPr': 'a',
'p:txBody': 'd',
apples: 'e',
5: 'eagle',
p:spPr: 'b'
}
const obj = orderKeys(example);
console.log(obj);
console.log(Object.keys(obj));
输出以下内容:
Babel Compiler v6.4.4
Copyright (c) 2014-2015 Sebastian McKenzie
{ 3: 'charlie',
5: 'eagle',
apples: 'e',
berries: 'e',
'p:nvSpPr': 'a',
'p:spPr': 'b',
'p:style': 'c',
'p:txBody': 'd' }
[ '3',
'5',
'apples',
'berries',
'p:nvSpPr',
'p:spPr',
'p:style',
'p:txBody' ]
state
对象的下拉菜单的选项进行排序,该对象是在我的 API 响应后分配的。一开始我是这么做的
return (
// ...
<Select
options={Object.keys(obj).sort()}
// ...
/>
// ...
);
但意识到每次重新渲染都会调用
.sort()
方法,因此需要@prototype 实现
orderKeys
。
_.chain(obj).toPairs().sortBy(0).fromPairs().value()
使用您的示例数据:
var data = {
'States': ['NSW', 'VIC'],
'Countries': ['GBR', 'AUS'],
'Capitals': ['SYD', 'MEL']
}
data = _.chain(data)
.toPairs() // turn the object into an array of [key, value] pairs
.sortBy(0) // sort these pairs by index [0] which is [key]
.fromPairs() // convert array of pairs back into an object {key: value}
.value() // return value
/*
{
Capitals: [ 'SYD', 'MEL' ],
Countries: [ 'GBR', 'AUS' ],
States: [ 'NSW', 'VIC' ]
}
*/
const sortObject = (obj: any) => {
const sorted = Object.keys(obj)
.sort()
.reduce((accumulator, key) => {
if (typeof obj[key] === "object") {
// recurse nested properties that are also objects
if (obj[key] == null) {
accumulator[key] = null;
} else if (isArray(obj[key])) {
accumulator[key] = obj[key].map((item: any) => {
if (typeof item === "object") {
return sortObject(item);
} else {
return item;
}
});
} else {
accumulator[key] = sortObject(obj[key]);
}
} else {
accumulator[key] = obj[key];
}
return accumulator;
}, {});
return sorted;
};
function orderKeys(obj: {}) {
var keys = (Object.keys(obj) as Array<keyof typeof obj>).sort((k1, k2) => {
if (k1 < k2) return -1;
else if (k1 > k2) return +1;
else return 0;
});
var helpArr = {};
for (var elem of keys) {
helpArr[elem] = obj[elem];
delete obj[elem];
obj[elem] = helpArr[elem]
}
return obj;
}
var data = {
'States': ['NSW', 'VIC'],
'Countries': ['GBR', 'AUS'],
'Capitals': ['SYD', 'MEL']
}
或者使用 ES6 和 reduce
const sorted = (Object.keys(data) as Array<keyof typeof data>).sort().reduce((r: any, k) => ({ ...r, [k]: data[k] }), {});
结果按键排序console.log(orderKeys(data)) # similar: console.log(sorted)
{
Capitals: [ 'SYD', 'MEL' ],
Countries: [ 'GBR', 'AUS' ],
States: [ 'NSW', 'VIC' ]
}
对于那些说对象是无序的人来说,这是不正确的。
const obj = {};
obj.c = 'c';
obj.b = 'b';
obj[1] = 1;
obj[-1] = -1;
obj.a = 'a';
如果我将对象字符串化,它将看起来像:
{
"1": 1,
"c": "c",
"b": "b",
"a": "a",
"-1": -1
}
注意 1
是如何位于开头的,尽管它不是第一个插入的键;
a
、
b
和
c
按插入顺序排列在下;
-1
是最后一个。鉴于 -1 小于 0,它被视为字符串键,因为它不能用于索引零索引数组。它是最后插入的,因此位于最后一个位置。就地对对象进行排序的一种非常干净的方法是按字母顺序逐一删除并重新插入属性。这将更改属性的插入顺序。
const sortObjectProperties = (obj) => {
Object.entries(obj)
.sort(([a], [b]) => (a < b ? -1 : 1))
.forEach(([key, value]) => {
delete obj[key];
obj[key] = value;
});
return obj;
};
在控制器中定义一个数组,其中键的顺序正确:
this.displayOrder = [
'firstKey',
'secondKey',
'thirdKey'
];
在模板中重复 displayOrder 的键,然后使用 ng-init 引用回您的对象。
<div ng-repeat="key in ctrl.displayOrder" ng-init="entry = ctrl.object[key]">
{{ entry.detail }}
</div>