对 Javascript 对象中的键进行排序

Sort Keys in Javascript Object

我有一个 Javascript 对象,它包含 属性 类型的混合,包括简单字符串、对象、对象数组...等等。

我想按照以下规则对键进行排序:

'Simple properties like strings or numbers appears always before more complex properties that contains arrays or objects'

我编写了以下函数,它几乎完成了我想要实现的目标,但它将数组转换为对象。这不是期望的行为。谁能帮我创建一个函数,将数组保存为数组,同时对数组中的对象进行排序?

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

工作 jsfiddle:

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

亲切的问候

从 ECMAScript 2015 (ES6) 开始,对象的 own 属性 do have order 用于某些操作,尽管依赖它很少是一个好主意。如果你想要顺序,通常最好使用数组或类似的东西。

顺序是:

  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
    • Add P as the last element of keys.
  3. For each own property key P of O that is a String but is not an integer index, in property creation order
    • Add P as the last element of keys.
  4. For each own property key P of O that is a Symbol, in property creation order
    • Add P as the last element of keys.
  5. Return keys.

那是 "own" 属性。 我认为没有任何外部可用的操作可以定义所有属性(包括继承属性)的必需顺序。 (for-in 不需要遵循上面的顺序,甚至在 ES2015+ 中也不需要。) 从 ES2019 开始,for-in does have a defined order (有一些例外) .

这意味着如果我们的 none 个键符合​​整数索引的条件,那么在兼容的引擎上可能会执行您的要求。

JSON 仍然没有顺序,但是 JavaScript 规范要求 JSON.stringify 使用上述顺序。

我不是说我建议它。 :-)

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;
}

实例(我也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>

(您没有要求在类别中按字母顺序排列,但放入其中似乎是合理的。)

这适用于当前的 Chrome、Firefox 和 IE11。

我知道我无法按照 javascript 属性顺序进行转发,但我需要在视觉上显示已排序 JSON。这样解决:

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;
}