Javascript - maintain key order when going from object -> array

后端 未结 3 678
时光说笑
时光说笑 2021-01-14 08:08

I know key order isn\'t guaranteed in JS objects, however, my data structure comes from a backend for which I have no control over. Is there anything I can do to preserve th

相关标签:
3条回答
  • 2021-01-14 08:18

    No. As you wrote:

    I know key order isn't guaranteed in JS objects

    If you want the order you need to use an array. If you have an object, then there is no defined order to the properties.

    0 讨论(0)
  • 2021-01-14 08:22

    The JSON specification indicates that

    An object is an unordered collection of zero or more name/value pairs...

    Strictly speaking, the literal JSON text has an order, of course: the text isn't going to suddenly scramble itself. But your desired behavior -- an ordered set of name/value pairs -- is not a construct that JSON provides. You want an object notation to provide semantic meaning beyond the semantics that are required by the JSON specification.

    In order words, doing this in JSON

    {
        "foo": "baz",
        "bar": "egg" 
    }
    

    is description of an unordered set. If you intended for this to describe an ordered set, you're not following the rules of JSON. The data happens to be ordered (because that's how character sequences work), but JSON semantics freely allow an implementation to disregard the order of name/value pairs completely when considering the data present in the input string.

    You could write code that operates directly on the JSON input string, to parse the text in such a way that the input order of the keys is remembered somewhere, but a JSON parser implementation is not required to supply that functionality to you.

    The correct JSON-idiomatic solution would be to provide an array of key names in the JSON response:

    {
        data: {
            "foo": "baz",
            "bar": "egg" 
        },
        order: ["foo", "bar"]
    }
    

    Obviously, if you don't control the response, you can't do that. By choosing the represent the data in an object, the author of the response has asserted that order of keys is purely arbitrary. If the author of the JSON intends to assert order of key entries, that assertion is external to the rules of JSON.

    As a practical matter, most JavaScript engines will usually choose to report key names in the order their properties were created. However, this behavior is not required by any specification (and is sometimes inconsistent in edge cases), and so could legally differ between engines and versions.

    0 讨论(0)
  • 2021-01-14 08:28

    ECMA-262 does not specify enumeration order. The de facto standard is to match insertion order.

    No guarantees are given though on the enumeration order for array indices (i.e., a property name that can be parsed as an integer), because insertion order for array indices would incur significant memory overhead.

    EDIT: added jsfiddle example.

    var obj1 = {
       a: 'test1',
       b: 'test2' 
    };
    
    var obj2 = {
       2: 'test1',
       1: 'test2' 
    };
    // max 32bit unsigned is 2,147,483,647
    var obj3 = {
       2147483649: 'test1',
       2147483648: 'test2' 
    };
    // max 64bit unsigned is 9,223,372,036,854,775,807
    var obj4 = {
       9223372036854770: 'test1',
       9223372036854768: 'test2',
    };
    
    // != number < 2,147,483,647, order is not changed
    console.log(Object.keys(obj1));
    // < 2,147,483,647, order is changed
    console.log(Object.keys(obj2));
    // > 2,147,483,647, order is not changed in Firefox, but changed in Chrome
    console.log(Object.keys(obj3));
    // > 9,223,372,036,854,775,807, order is not changed in neither Firefox or Chrome
    console.log(Object.keys(obj4));
    

    Which means Chrome's javascript engine V8 will order any 64bit unsigned numbers, while Firefox's javascript engine SpiderMonkey will order any 32bit unsigned numbers.

    0 讨论(0)
提交回复
热议问题