javascriptkeyjavascript-objectsreduceinsertion-order

Sorting Object of Object with sort and reduce function


I have an object like this

//input
let data={
    "51": {"name": "text51"},
    "54": {"name": "text54"},
    "61": {"name": "text61"},
    "64": {"name": "text64"},
    "71": {"name": "text71"},
    "74": {"name": "text74"},
    "81": {"name": "text81"},
    "84": {"name": "text84"}
}

/*
targeted output
{
    "51": {"name": "text51"},
    "61": {"name": "text61"},
    "71": {"name": "text71"},
    "81": {"name": "text81"},
    "54": {"name": "text54"},
    "64": {"name": "text64"},
    "74": {"name": "text74"},
    "84": {"name": "text84"}
}
*/

I sort it base on the digit of the keys.

new_key=Object.keys(data).sort((a, b)=>parseInt(a.slice(-1)) - parseInt(b.slice(-1)));
//output is ---> ['51', '61', '71', '81', '54', '64', '74', '84']

Now I want to rearrange the object base on the above output. (I did that)

result=new_key.reduce((r, k) => {
    console.log(r);
    r[k] = data[k];
    return r;
}, {});

When I console.log(r) for each iteration I got this:

enter image description here

My question is why when 54 key came it went to the middle of the object instead of going to the end.


Solution

  • Object keys order was not guaranteed earlier in JS. Now it is. But here is how it is going to be.

    What matters here is for integer like keys, the order will be ascending.

    For string keys it is order of insertion, which can be tested by appending a character to the integer every time.

    let data={
        "51": {"name": "text51"},
        "54": {"name": "text54"},
        "61": {"name": "text61"},
        "64": {"name": "text64"},
        "71": {"name": "text71"},
        "74": {"name": "text74"},
        "81": {"name": "text81"},
        "84": {"name": "text84"}
    };
    
    let new_key=Object.keys(data).sort((a, b)=>parseInt(a.slice(-1)) - parseInt(b.slice(-1)));
    
    let result=new_key.reduce((r, k) => {
        console.log(r);
        r['x-' + k] = data[k];
        return r;
    }, {});