简体   繁体   English

Javascript 对象中的排序键

[英]Sort Keys in Javascript Object

I have a Javascript Object that contains a mix of property types including simple strings, objects, arrays of objects... and so on.我有一个 Javascript 对象,它包含多种属性类型,包括简单的字符串、对象、对象数组……等等。

I would like to sort the keys following this rule:我想按照此规则对键进行排序:

'Simple properties like strings or numbers appears always before more complex properties that contains arrays or objects' '像字符串或数字这样的简单属性总是出现在包含数组或对象的更复杂的属性之前'

I wrote the following function, that almost do what I am trying to achieve, but it converts the arrays into objects.我编写了以下函数,几乎可以完成我想要实现的功能,但它将数组转换为对象。 This is not the desired behaviour.这不是理想的行为。 Can anybody help me to create a function that keep arrays as arrays and at the same time it sorts the objects inside arrays?谁能帮我创建一个函数,将数组保存为数组,同时对数组内的对象进行排序?

function sort(object){
    if (typeof object != "object" )
        return object;
    var keys = Object.keys(object);
    keys.sort(function(a,b){
            if (typeof(object[a])!== 'object') { return -1 } else { return 1 }
        });

Working jsfiddle:工作jsfiddle:

http://jsfiddle.net/u01mn2py/3/ http://jsfiddle.net/u01mn2py/3/

Kind Regards亲切的问候

As of ECMAScript 2015 (ES6), an object's own propertiesdo have order for some operations, although relying on it is rarely a good idea.从 ECMAScript 2015 (ES6) 开始,对象自己的属性确实对某些操作具有顺序,尽管依赖它很少是一个好主意。 If you want order, usually it's best to use an array or similar.如果你想要顺序,通常最好使用数组或类似的。

The order is:顺序是:

  1. Let keys be a new empty List.成为一个新的空列表。
  2. For each own property key P of O that is an integer index, in ascending numeric index order对于作为整数索引的O 的每个自己的属性键P ,按升序数字索引顺序
    • Add P as the last element of keys .添加P作为keys的最后一个元素。
  3. For each own property key P of O that is a String but is not an integer index, in property creation order对于是字符串但不是整数索引的O 的每个自己的属性键P ,按属性创建顺序
    • Add P as the last element of keys .添加P作为keys的最后一个元素。
  4. For each own property key P of O that is a Symbol, in property creation order对于作为符号的O 的每个自己的属性键P ,按属性创建顺序
    • Add P as the last element of keys .添加P作为keys的最后一个元素。
  5. Return keys .返回

That's for "own" properties.那是“自己的”属性。 I don't think there are any externally-available operations that define a required order for all properties including inherited ones.我认为没有任何外部可用操作为所有属性(包括继承的属性)定义所需的顺序。 ( for-in is not required to follow the order above, not even in ES2015+.) As of ES2019, for-in does have a defined order (with some exceptions) . for-in不需要遵循上面的顺序,即使在 ES2015+ 中也不需要。)从 ES2019 开始, for-in确实有一个定义的顺序(有一些例外)

This means that it's probably possible to do what you asked, on a compliant engine, provided none of our keys qualifies as as an integer index.这意味着如果我们的键都不符合整数索引的条件,则可能可以在兼容引擎上执行您的要求。

JSON still has no order, but JSON.stringify is required by the JavaScript spec to use the order described above. JSON 仍然没有顺序,但 JavaScript 规范要求JSON.stringify使用上述顺序。

I'm not saying I suggest it.我不是说我建议它。 :-) :-)

function sort(object) {
    // Don't try to sort things that aren't objects
    if (typeof object != "object") {
        return object;
    }

    // Don't sort arrays, but do sort their contents
    if (Array.isArray(object)) {
        object.forEach(function(entry, index) {
            object[index] = sort(entry);
        });
        return object;
    }

    // Sort the keys
    var keys = Object.keys(object);
    keys.sort(function (a, b) {
        var atype = typeof object[a],
            btype = typeof object[b],
            rv;
        if (atype !== btype && (atype === "object" || btype === "object")) {
            // Non-objects before objects
            rv = atype === 'object' ? 1 : -1;
        } else {
            // Alphabetical within categories
            rv = a.localeCompare(b);
        }
        return rv;
    });

    // Create new object in the new order, sorting
    // its subordinate properties as necessary
    var newObject = {};
    keys.forEach(function(key) {
        newObject[key] = sort(object[key]);
    });
    return newObject;
}

Live Example (I also updated the fiddle ):现场示例(我还更新了小提琴):

 function sort(object) { // Don't try to sort things that aren't objects if (typeof object != "object") { return object; } // Don't sort arrays, but do sort their contents if (Array.isArray(object)) { object.forEach(function(entry, index) { object[index] = sort(entry); }); return object; } // Sort the keys var keys = Object.keys(object); keys.sort(function (a, b) { var atype = typeof object[a], btype = typeof object[b], rv; if (atype !== btype && (atype === "object" || btype === "object")) { // Non-objects before objects rv = atype === 'object' ? 1 : -1; } else { // Alphabetical within categories rv = a.localeCompare(b); } return rv; }); // Create new object in the new order, sorting // its subordinate properties as necessary var newObject = {}; keys.forEach(function(key) { newObject[key] = sort(object[key]); }); return newObject; } var object = { family: [{ home: { city: 'Madrid' }, birth: { city: 'Madrid' }, name: 'John', age: 32 }, { home: { city: 'London' }, birth: { city: 'Paris' }, name: 'Marie', age: 25 }], name: 'Dani', age: 33 }; var sortedObject = sort(object); document.getElementById('container').innerHTML = JSON.stringify(sortedObject, null, '\\t');
 <pre id="container"> </pre>

(You didn't ask for alphabetical within categories, but it seemed a reasonable thing to throw in.) (您没有要求在类别内按字母顺序排列,但扔进去似乎是一件合理的事情。)

That works for me on current Chrome, Firefox, and IE11.这适用于我当前的 Chrome、Firefox 和 IE11。

I know I can't relay on javascript properties order, but I need visually to show sorted JSON.我知道我无法传递 javascript 属性顺序,但我需要在视觉上显示排序的 JSON。 Solved in this way:以这种方式解决:

http://jsfiddle.net/u01mn2py/4/ http://jsfiddle.net/u01mn2py/4/

function sort(object){
    if (typeof object != "object" ) // Not to sort the array
        return object;
    var keys = Object.keys(object);
    keys.sort(function(a,b){
            if (typeof(object[a])!== 'object') { return -1 } else { return 1 }
        });
    if( Object.prototype.toString.call( object ) === '[object Array]' ) {
        var newObject = [];
     } else {
        var newObject = {}; }

     for (var i = 0; i < keys.length; i++){
            newObject[keys[i]] = sort(object[keys[i]])
      }
    return newObject;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM