伙计们,我很震惊!当然所有的答案都有些老了,但没有人提到排序的稳定性!所以请耐心等待,我会尽力回答问题本身并在此处详细介绍。所以我要道歉,现在要读的东西很多。
由于是 2018 年,我将只使用 ES6,所有 Polyfill 都可以在 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() 返回一个元素为字符串的数组
对应于直接在对象上找到的可枚举属性。
属性的顺序与循环给出的顺序相同
手动覆盖对象的属性。
旁注 - 您也可以在数组上使用 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 和数据库),人们往往会特别混淆事物。
那么有什么大不了的?
有两篇文章是每个程序员都应该了解的:
In-place algorithm:
在计算机科学中,就地算法是一种不使用辅助数据结构来转换输入的算法。然而,辅助变量允许有少量的额外存储空间。当算法执行时,输入通常被输出覆盖。就地算法仅通过替换或交换元素来更新输入序列。不就地的算法有时称为不就地或不就地。
所以基本上我们的旧数组将被覆盖!如果您出于其他原因想要保留旧阵列,这一点很重要。所以请记住这一点。
Sorting algorithm
稳定的排序算法以相同的顺序对相同的元素进行排序
它们出现在输入中。对某些类型的数据进行排序时,只有一部分
在确定排序顺序时会检查数据。例如,
在右边的卡片分类示例中,卡片正在被分类
按他们的等级,他们的西装被忽略了。这允许
多个不同的正确排序版本的可能性
原始清单。稳定的排序算法选择其中之一,
根据以下规则:如果两个项目比较相等,例如
两张5张牌,那么它们的相对顺序将被保留,这样
如果输入中一个在另一个之前,它也会在
另一个在输出中。
扑克牌稳定排序的一个例子。卡片分类时
按排名稳定的排序,两个 5 必须保持相同的顺序
在它们最初所在的排序输出中。当它们在
使用不稳定排序进行排序,5s 可能以相反的顺序结束
在排序后的输出中。
这表明排序是正确的,但它改变了。所以在现实世界中,即使排序是正确的,我们也必须确保得到我们期望的结果!这一点非常重要,请记住这一点。有关更多 JavaScript 示例,请查看 Array.prototype.sort() - 文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort