因此以下内容:
{ 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' }
将变成:
{ 'a' : 'dsfdsfsdf', 'b' : 'asdsad', 'c' : 'masdas' }
{ 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' }
将变成:
{ 'a' : 'dsfdsfsdf', 'b' : 'asdsad', 'c' : 'masdas' }
这个问题的其他答案已经过时,从未匹配实现现实,并且现在官方上已经因为ES6/ ES2015规范的发布而被正式视为不正确。
请参阅Axel Rauschmayer的 Exploring ES6 中关于属性迭代顺序的章节:
所有迭代属性键的方法都按相同的顺序执行:
- 首先是所有数组索引,按数字排序。
- 然后是所有字符串键(不是索引),按创建顺序排列。
- 最后是所有符号,按创建顺序排列。
因此,JavaScript对象实际上是有序的,它们的键/属性的顺序可以更改。
以下是如何按字母顺序对对象的键/属性进行排序:
const unordered = {
'b': 'foo',
'c': 'bar',
'a': 'baz'
};
console.log(JSON.stringify(unordered));
// → '{"b":"foo","c":"bar","a":"baz"}'
const ordered = Object.keys(unordered).sort().reduce(
(obj, key) => {
obj[key] = unordered[key];
return obj;
},
{}
);
console.log(JSON.stringify(ordered));
// → '{"a":"baz","b":"foo","c":"bar"}'
使用 var
替代 const
,以确保与 ES5 引擎兼容。
JavaScript对象1是无序的。尝试"排序"它们是没有意义的。如果你想遍历一个对象的属性,你可以对键进行排序,然后检索相应的值:
var myObj = {
'b': 'asdsadfd',
'c': 'masdasaf',
'a': 'dsfdsfsdf'
},
keys = [],
k, i, len;
for (k in myObj) {
if (myObj.hasOwnProperty(k)) {
keys.push(k);
}
}
keys.sort();
len = keys.length;
for (i = 0; i < len; i++) {
k = keys[i];
console.log(k + ':' + myObj[k]);
}
使用Object.keys
函数的另一种实现方式:
var myObj = {
'b': 'asdsadfd',
'c': 'masdasaf',
'a': 'dsfdsfsdf'
},
keys = Object.keys(myObj),
i, len = keys.length;
keys.sort();
for (i = 0; i < len; i++) {
k = keys[i];
console.log(k + ':' + myObj[k]);
}
1虽不想显得过于学究,但是JSON对象并不存在。
{"a", 1}
这样的字符串,就像“JSON数组”是指[1]
这样的字符串。当你使用字符串[{x: 1}, {y: 2}, {z: 3}]
时,能够说出“我的数组中的第三个对象”是很有用的。因此,当评论JavaScript字面量时,我更喜欢使用“那不是一个JSON对象”,而不是“不存在JSON对象”,后者只会在OP实际处理JSON时导致更多的混乱和沟通困难。 - Paul{"a", 1}
可以是对象字面量或JSON文本(如果你愿意的话也可以称为JSON字符串)。它是哪一个取决于上下文,如果它在JavaScript源代码中直接出现,则为前者;如果它是需要传递给JSON解析器以进一步使用的字符串,则为后者。在允许的语法、正确的用法和序列化方面,这两者之间确实存在真正的差异。 - Matt Ballfunction sortObject(obj) {
return Object.keys(obj).sort().reduce(function (result, key) {
result[key] = obj[key];
return result;
}, {});
}
以上为ES2015版本(格式化成“单行”):
const sortObject = o => Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {})
上面示例的简要说明(根据评论要求):
Object.keys
给我们提供了一个提供对象(obj
或o
)中键的列表,然后我们使用默认排序算法对这些键进行排序,接下来使用.reduce
将该数组转换回对象,但这次所有键都已排序。
for...in
)。 - Felix Klingconst sortObject = o => Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {})
。 - cchamberlainObject.keys(dict).sort().reduce((r, k) => Object.assign(r, { [k]: dict[k] }), {});
- aks.各位,我感到震惊!虽然所有的答案都有点老,但没有人提到排序中的稳定性!所以请耐心等待,我会尽力回答问题并在此详细说明。因此,我现在要道歉,这将是一篇很长的阅读。
由于现在是2018年,我将只使用ES6,Polyfills都可以在MDN文档中找到,我会在相应部分提供链接。
问题的答案:
如果你的键只是数字,那么你可以安全地使用Object.keys()
和Array.prototype.reduce()
来返回排序后的对象:
// Only numbers to show it will be sorted.
const testObj = {
'2000': 'Articel1',
'4000': 'Articel2',
'1000': 'Articel3',
'3000': 'Articel4',
};
// I'll explain what reduces does after the answer.
console.log(Object.keys(testObj).reduce((accumulator, currentValue) => {
accumulator[currentValue] = testObj[currentValue];
return accumulator;
}, {}));
/**
* expected output:
* {
* '1000': 'Articel3',
* '2000': 'Articel1',
* '3000': 'Articel4',
* '4000': 'Articel2'
* }
*/
// if needed here is the one liner:
console.log(Object.keys(testObj).reduce((a, c) => (a[c] = testObj[c], a), {}));
然而,如果你正在处理字符串,我强烈建议将Array.prototype.sort()
链接到所有这些操作中:
// String example
const testObj = {
'a1d78eg8fdg387fg38': 'Articel1',
'z12989dh89h31d9h39': 'Articel2',
'f1203391dhj32189h2': 'Articel3',
'b10939hd83f9032003': 'Articel4',
};
// Chained sort into all of this.
console.log(Object.keys(testObj).sort().reduce((accumulator, currentValue) => {
accumulator[currentValue] = testObj[currentValue];
return accumulator;
}, {}));
/**
* expected output:
* {
* a1d78eg8fdg387fg38: 'Articel1',
* b10939hd83f9032003: 'Articel4',
* f1203391dhj32189h2: 'Articel3',
* z12989dh89h31d9h39: 'Articel2'
* }
*/
// again the one liner:
console.log(Object.keys(testObj).sort().reduce((a, c) => (a[c] = testObj[c], a), {}));
如果有人想知道reduce的作用:
// Will return Keys of object as an array (sorted if only numbers or single strings like a,b,c).
Object.keys(testObj)
// Chaining reduce to the returned array from Object.keys().
// Array.prototype.reduce() takes one callback
// (and another param look at the last line) and passes 4 arguments to it:
// accumulator, currentValue, currentIndex and array
.reduce((accumulator, currentValue) => {
// setting the accumulator (sorted new object) with the actual property from old (unsorted) object.
accumulator[currentValue] = testObj[currentValue];
// returning the newly sorted object for the next element in array.
return accumulator;
// the empty object {} ist the initial value for Array.prototype.reduce().
}, {});
Object.keys(testObj).reduce(
// Arrow function as callback parameter.
(a, c) =>
// parenthesis return! so we can safe the return and write only (..., a);
(a[c] = testObj[c], a)
// initial value for reduce.
,{}
);
为什么排序有点复杂:
简而言之,Object.keys()
将返回一个与普通循环得到的顺序相同的数组:
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]
顺便提一下 - 你也可以在数组上使用Object.keys()
,但要记住返回的是索引:
// simple array
const arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
但实际上并不像示例所展示的那样简单,现实世界的对象可能包含数字、字母或甚至符号(请勿这样做)。
以下是一个包含所有这些元素的对象示例:
// This is just to show what happens, please don't use symbols in keys.
const testObj = {
'1asc': '4444',
1000: 'a',
b: '1231',
'#01010101010': 'asd',
2: 'c'
};
console.log(Object.keys(testObj));
// output: [ '2', '1000', '1asc', 'b', '#01010101010' ]
Array.prototype.sort()
,输出会发生变化:console.log(Object.keys(testObj).sort());
// output: [ '#01010101010', '1000', '1asc', '2', 'b' ]
以下是文档中的引用:
sort()方法会就地对数组元素进行排序,并返回该数组。排序不一定是稳定的。默认的排序顺序是按照字符串Unicode代码点的顺序。
排序的时间和空间复杂度不能保证,因为它取决于具体实现。
你必须确保其中一个返回所需的输出。在现实生活中的例子中,人们往往会混淆事情,尤其是当你同时使用不同的信息输入,如API和数据库时。
那么这有什么大不了的?
嗯,有两篇文章是每个程序员都应该理解的:
原地算法:
在计算机科学中,原地算法是一种不使用辅助数据结构来转换输入的算法。但是允许为辅助变量使用少量额外存储空间。随着算法执行,通常会将输出覆盖输入。原地算法仅通过替换或交换元素来更新输入序列。未进行原地处理的算法有时被称为非原地或就地外部算法。
所以基本上我们的旧数组将被覆盖!如果您想因其他原因保留旧数组,则这很重要。请记住这一点。
一种对扑克牌进行稳定排序的示例。当使用稳定排序按等级对牌进行排序时,两个5必须保持与原始顺序相同的顺序出现在排序后的输出中。当使用非稳定排序进行排序时,5可能以相反的顺序出现在排序后的输出中。这表明排序是正确的,但它发生了变化。因此,在现实世界中,即使排序是正确的,我们也必须确保我们得到了预期的结果!这非常重要,请记住这一点。有关更多JavaScript示例,请查看Array.prototype.sort() - docs:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort。稳定排序算法按照相同顺序排序相同的元素,就像它们在输入中出现的顺序一样。当对某些类型的数据进行排序时,只有部分数据在确定排序顺序时被检查。例如,在右侧的卡牌排序示例中,正在按其等级对卡牌进行排序,并忽略其花色。这允许多个不同的正确排序版本的原始列表。稳定的排序算法根据以下规则选择其中之一:如果两个项目相等(如两个5卡),则它们的相对顺序将被保留,以便如果一个在输入中出现在另一个之前,则它也将在输出中出现在另一个之前。
Array.prototype.sort()
的文档说明它在所有现代浏览器中都是稳定的。这是否意味着从示例中排序卡片的结果将始终相同? - Arthur Stankevich现在是2023年,我们有一种解决这个问题的方法 :)
Object.fromEntries(Object.entries({b: 3, a:8, c:1}).sort())
Object.fromEntries(Object.entries({b: 3, a:8, c:1}).sort(([key1, val1], [key2, val2]) => key1.toLowerCase().localeCompare(key2.toLowerCase())))
- BenObject.entries({ a: 8, ['a,1']: 6 }).sort()
-> [ [ 'a,1', 6 ], [ 'a', 8 ] ]
。 - xmedeko,
字符,则结果顺序将受到影响。Object.fromEntries(Object.entries({'a.': 1, 'a': 2, 'a,': 234}).sort())
- {a,: 234, a: 2, a.: 1}
,至少它不会是ASCII顺序。 - KlesunES6-这里是一行代码
var data = { zIndex:99,
name:'sravan',
age:25,
position:'architect',
amount:'100k',
manager:'mammu' };
console.log(Object.entries(data).sort().reduce( (o,[k,v]) => (o[k]=v,o), {} ));
(o[k] = v, o)
。为什么它能够工作,我在哪里可以找到相关文档?显然它返回最右边的参数,但为什么呢? - ntasoo[k]
等于 v
,然后返回 o
。 - Tahsin Turkoz这对我有效
/**
* Return an Object sorted by it's Key
*/
var sortObjectByKey = function(obj){
var keys = [];
var sorted_obj = {};
for(var key in obj){
if(obj.hasOwnProperty(key)){
keys.push(key);
}
}
// sort keys
keys.sort();
// create new array based on Sorted Keys
jQuery.each(keys, function(i, key){
sorted_obj[key] = obj[key];
});
return sorted_obj;
};
这是一个老问题,但借鉴Mathias Bynens的回答,我做了一个简短的版本来对 当前 对象进行排序,没有太多额外的开销。
Object.keys(unordered).sort().forEach(function(key) {
var value = unordered[key];
delete unordered[key];
unordered[key] = value;
});
在代码执行后,“unordered”对象本身的键将按字母顺序排序。
(function(s) {
var t = {};
Object.keys(s).sort().forEach(function(k) {
t[k] = s[k]
});
return t
})({
b: 2,
a: 1,
c: 3
});
(function(s){var t={};Object.keys(s).sort().forEach(function(k){t[k]=s[k]});return t})({b:2,a:1,c:3})
使用lodash,这将起作用:
some_map = { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' }
// perform a function in order of ascending key
_(some_map).keys().sort().each(function (key) {
var value = some_map[key];
// do something
});
// or alternatively to build a sorted list
sorted_list = _(some_map).keys().sort().map(function (key) {
var value = some_map[key];
// return something that shall become an item in the sorted list
}).value();
只是思考的食物。
Object.entries
和Object.fromEntries
被添加到 JS 中以来,可以使用一个漂亮的一行代码实现此操作:Object.fromEntries(Object.entries(obj).sort())
。 - Mike 'Pomax' Kamermans