在Javascript对象中排序键 [英] Sort Keys in Javascript Object

查看:72
本文介绍了在Javascript对象中排序键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Javascript对象,其中包含各种属性类型,包括简单字符串,对象,对象数组......等等。



我想要按照此规则对键进行排序:



'字符串或数字等简单属性总是出现在包含数组或对象的更复杂属性之前



我编写了以下函数,它几乎完成了我想要实现的功能,但它将数组转换为对象。这不是理想的行为。任何人都可以帮我创建一个函数,将数组保持为数组,同时对数组中的对象进行排序吗?

  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更新。)



JavaScript对象中的属性没有订单。您无法在 for-in 循环或类似循环中控制访问属性的顺序。



某些特定的实现似乎可以演示某种形式的顺序(例如,属性添加到对象的顺序),但这是未定义的行为,您不能依赖它。



如果您需要订单,则需要一组属性名称然后循环以获得所需顺序的属性值。这不会改变对象中属性的顺序(没有),它只是让你可以按照你想要的顺序访问这些属性。






更新:从ECMAScript 2015(ES6)开始,属性有订单:



  1. 成为新的空列表。

  2. 对于每个属性 O P 是一个整数索引,按升序数字索引顺序


    • 添加 P 作为键的最后一个元素


  3. 对于每个自己的属性键 O O 是一个字符串但不是整数索引,在属性创建顺序中


    • 添加 P 作为键的最后一个元素


  4. 对于每个自己的属性键 O O 是一个符号,在属性创建顺序中


    • 添加 P 作为键的最后一个元素


  5. 返回


这是自有属性;然后是对象的原型属性,按照相同的顺序(忽略已经被遮蔽的那些),依此类推。



这意味着它可能是在合规引擎上做你所问的。 JSON仍然没有订单,但我给出了任何浏览器的 JSON.stringify 将使用对象迭代来完成其工作的几率,所以它可能 (不保证!)生成的JSON将按照您为对象创建的顺序。



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

 函数sort(object){
//不要尝试排序不是对象
if(typeof object!=object){
return object;
}

//不要对数组进行排序,而是对它们的内容进行排序
if(Array.isArray(object)){
object.forEach(function( entry,index){
object [index] = sort(entry);
});
返回对象;
}

//对键进行排序
var keys = Object.keys(object);
keys.sort(函数(a,b){
var atype = typeof object [a],
btype = typeof object [b],
rv;
if(atype!== btype&&(atype ===object|| btype ===object)){
//对象之前的非对象
rv = atype = =='object'?1:-1;
} else {
//按字母顺序分类
rv = a.localeCompare(b);
}
返回rv;
});

//在新订单中创建新对象,根据需要排序
//其下属属性
var newObject = {};
keys.forEach(function(key){
newObject [key] = sort(object [key]);
});
返回newObject;
}

更新小提琴



(您没有要求按类别划分字母,但是扔进去似乎是合情合理的。)



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


I have a Javascript Object that contains a mix of property types including simple strings, objects, arrays of objects... and so on.

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:

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

Kind Regards

解决方案

(See ECMAScript 2015 update below.)

Properties in JavaScript objects have no order. You cannot control the order in which the properties are visited in a for-in loop or similar.

Some specific implementations may seem to demonstrate some form of order (for instance, the order in which the properties were added to the object), but this is undefined behavior and you cannot rely on it.

If you want order, you'll need an array of property names that you then loop through to get the property values in your desired order. That doesn't change the order of the properties in the object (there is none), it just makes it possible for you to visit those properties in the order you want.


Update: As of ECMAScript 2015 (ES6), properties 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.

That's for "own" properties; they're then followed by the object's prototype's properties, in the same order (ignoring those that have been shadowed), and so on.

This means that it's probably possible to do what you asked, on a compliant engine. JSON still has no order, but I'd give odds that any browser's JSON.stringify is going to use object iteration to do its job, so it's likely (not guaranteed!) that the resulting JSON will be in the order you create for the object.

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

Updated Fiddle

(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.

这篇关于在Javascript对象中排序键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆