我需要按关键字对JavaScript对象进行排序。

因此如下:

{ 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' }

将变成:

{ 'a' : 'dsfdsfsdf', 'b' : 'asdsad', 'c' : 'masdas' }

当前回答

很多人都提到“对象无法排序”,但在那之后,他们给了你一个可行的解决方案。矛盾,不是吗?

没有人提及这些解决方案为何奏效。它们是这样的,因为在大多数浏览器的实现中,对象中的值是按照添加它们的顺序存储的。这就是为什么如果您从排序的键列表中创建新对象,它将返回预期结果。

我认为我们可以再增加一个解决方案——ES5功能方式:

function 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将数组转换回对象,但这次对所有键进行了排序。

其他回答

伙计们,我简直惊呆了!当然,所有的答案都有些陈旧,但没有人提到排序的稳定性!所以请耐心等待,我会尽力回答这个问题,并在这里详细说明。所以我现在要道歉,这将是很多阅读。

由于是2018年,我将只使用ES6,Polyfills都可以在MDN文档中找到,我将在给定部分链接。


问题的答案:

如果你的键只是数字,那么你可以安全地使用Object.keys()和Array.protocol.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.
  ,{}
);

减少的文件:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce为什么在JavaScript返回语句中使用括号:http://jamesknelson.com/javascript-return-parenthesis/


为什么排序有点复杂:

简而言之,Object.keys()将返回一个数组,其顺序与我们使用普通循环得到的顺序相同:

const object1 = {
  a: 'somestring',
  b: 42,
  c: false
};

console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]

Object.keys()返回元素为字符串的数组对应于直接在对象上找到的可枚举财产。财产的顺序与循环给出的顺序相同手动覆盖对象的财产。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/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.protocol.sort(),输出将发生变化:

console.log(Object.keys(testObj).sort());
// output: [ '#01010101010', '1000', '1asc', '2', 'b' ]

以下是文档中的引用:

sort()方法就地对数组的元素进行排序并返回阵列。排序不一定稳定。默认排序顺序是根据字符串Unicode代码点。排序的时间和空间复杂性无法保证取决于实现。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

您必须确保其中一个为您返回所需的输出。在现实生活中,如果你同时使用不同的信息输入(如API和数据库),人们往往会把事情搞混。


那有什么大不了的?

每个程序员都应该理解以下两篇文章:

就地算法:

在计算机科学中,就地算法是一种不使用辅助数据结构转换输入的算法。但是,允许为辅助变量提供少量的额外存储空间。当算法执行时,输入通常被输出覆盖。就地算法仅通过替换或交换元素来更新输入序列。不到位的算法有时被称为不到位或不到位。

所以基本上我们的旧阵列将被覆盖!如果出于其他原因想保留旧阵列,这一点很重要。所以请记住这一点。

排序算法

稳定排序算法以与它们出现在输入中。对某些类型的数据进行排序时,仅部分在确定排序顺序时检查数据的排序。例如在右边的卡片排序示例中,卡片正在排序而他们的诉讼却被忽视了。这允许多个不同的正确排序版本的可能性原始列表。稳定的排序算法选择其中之一,根据以下规则:如果两项比较相等,例如两张5卡,则它们的相对顺序将被保留,这样如果输入中的一个在另一个之前,它也会在前面另一个在输出中。

扑克牌中的一个稳定类型的例子。卡片分类时按稳定排序排序,两个5s必须保持相同的顺序在它们最初所在的排序输出中用非稳定排序,5s可能以相反的顺序结束在排序的输出中。

这表明排序是正确的,但它发生了变化。所以在现实世界中,即使排序是正确的,我们也必须确保得到我们期望的结果!这是非常重要的,请记住这一点。有关更多JavaScript示例,请查看Array.prototype.sort()-docs:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

我将一些Java枚举转换为javascript对象。

这些对象为我返回了正确的数组。如果对象键是混合类型(string、int、char),则存在问题。

var助手={isEmpty:函数(obj){回来obj | | obj===null | | obj===未定义| | Array.isArray(obj)&&obj.length===0;},isObject:函数(obj){return(对象类型==“object”);},sortObjectKeys:函数(对象){return Object.keys(对象).sort(函数(a,b){c=a-b;返回c});},containsItem:函数(arr,item){if(arr&&Array.isArray(arr)){return arr.indexOf(项)>-1;}其他{返回arr==项;}},pushArray:函数(arr1,arr2){if(arr1&&arr2&&Array.isArray(arr1)){arr1.push.apply(arr1,Array.isArray(arr2)?arr2:[arr2]);}}};函数TypeHelper(){var_types=参数[0],_defTypeIndex=0,_电流类型,_价值;if(arguments.length==2){_defTypeIndex=参数[1];}对象定义属性(this{关键字:{get:函数(){return _currentType;},集合:函数(val){_currentType.setType(val,true);},可枚举:真},值:{get:函数(){返回类型[_currentType];},集合:函数(val){_value.setType(val,false);},可枚举:真}});this.getAsList=函数(键){var列表=[];Helper.sortObjectKeys(_types).forEach(函数(键、idx、数组){if(键和类型[key]){if(!Helper.isEmpty(keys)&&Helper.containsItem(keys,key)|| Helper.isEmpty(key)){var json={};json.Key=密钥;json.Value=_types[key];Helper.pushArray(列表,json);}}});返回列表;};this.setType=函数(值,isKey){if(!Helper.isEmpty(value)){Object.keys(_types).forEach(函数(key,idx,array){if(Helper.isObject(值)){if(value&&value.Key==Key){_currentType=键;}}else if(isKey){if(value&&value.toString()==key.toString()){_currentType=键;}}否则如果(value&&value.toString()==_types[key]){_currentType=键;}});}其他{this.setDefaultType();}return isKey_类型[_currentType]:_currentType;};this.setTypeByIndex=函数(索引){var keys=Helper.sortObjectKeys(_types);对于(var i=0;i<keys.length;i++){如果(索引==i){_currentType=键[index];打破}}};this.setDefaultType=函数(){this.setTypeByIndex(_defTypeIndex);};this.setDefaultType();}变量类型A={“-1”:“任意”,“2”:“2L”,“100”:“100L”,“200”:“200L”,“1000”:“1000升”};变量类型B={“U”:“任意”,“W”:“1L”,“V”:“2L”,“A”:“100L”,“Z”:“200L”,“K”:“1000L”};console.log('keys of TypeA',Helper.sortObjectKeys(TypeA))//A类钥匙[“-1”、“2”、“100”、“200”、“1000”]console.log('keys of TypeB',Helper.sortObjectKeys(TypeB))//B类键[“U”、“W”、“V”、“A”、“Z”、“K”]var objectTypeA=新TypeHelper(TypeA),objectTypeB=新的TypeHelper(TypeB);console.log('listofobjectA=',objectTypeA.getAsList());console.log('listofobjectB=',objectTypeB.getAsList());

Types:

var TypeA = {
    "-1": "Any",
    "2": "2L",
    "100": "100L",
    "200": "200L",
    "1000": "1000L"
};

var TypeB = {
    "U": "Any",
    "W": "1L",
    "V": "2L",
    "A": "100L",
    "Z": "200L",
    "K": "1000L"
};


Sorted Keys(output):

Key list of TypeA -> ["-1", "2", "100", "200", "1000"]

Key list of TypeB -> ["U", "W", "V", "A", "Z", "K"]
function sortObjectKeys(obj){
    return Object.keys(obj).sort().reduce((acc,key)=>{
        acc[key]=obj[key];
        return acc;
    },{});
}

sortObjectKeys({
    telephone: '069911234124',
    name: 'Lola',
    access: true,
});

这对我有用

/**
 * 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;
    });

代码执行后,“无序”对象本身将按字母顺序对键进行排序。