使用排序和减少功能对对象的对象进行排序

Sorting Object of Object with sort and reduce function

我有一个这样的对象

//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"}
}
*/

我根据键的数字排序。

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']

现在我想根据上面的输出重新排列对象。 (我做到了)

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

当我对每次迭代 console.log(r) 时,我得到了这个:

我的问题是为什么当 54 键出现时它会到达对象的中间而不是最后。

早期的 JS 不保证对象键的顺序。现在它是。但这是 be.

的发展方向

这里重要的是对于像键这样的整数,顺序将是升序

对于字符串键是插入顺序,可以通过每次在整数后附加一个字符来测试。

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

您不能定义自己的对象键排序,因为浏览器(和 ES 规范)往往会进行自己的排序。

您可以在 Whosebug 上找到大量问题和答案(几个示例:ES5,

如果您真的很在意顺序,我建议您改用数组。

console.log(
  Object.entries({

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

  }).sort(([aKey], [bKey]) => {

    const aInt = parseInt(aKey.split('').reverse().join(''), 10);
    const bInt = parseInt(bKey.split('').reverse().join(''), 10);
    return aInt - bInt;

  }).reduce((result, [key, value]) =>

    // - key insertion prescedence/order is guaranteed since ES6/ES2015.
    //
    // - but is does not apply for pure digit based keys.
    // - insertion of the latter is handled by an ascending key order.
    //
    // ... try ...
    Object.assign(result, { [key]: value }), {}
    // ... versus ...
    // Object.assign(result, { [`_${ key }`]: value }), {}
  )
);
console.log(
  Object.entries({

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

  }).sort(([aKey], [bKey]) => {

    const aInt = parseInt(aKey.split('').reverse().join(''), 10);
    const bInt = parseInt(bKey.split('').reverse().join(''), 10);
    return aInt - bInt;

  }).reduce((result, [key, value]) =>

    // - key insertion prescedence/order is guaranteed since ES6/ES2015.
    //
    // - but is does not apply for pure digit based keys.
    // - insertion of the latter is handled by an ascending key order.
    //
    // ... try ...
    // Object.assign(result, { [key]: value }), {}
    // ... versus ...
    Object.assign(result, { [`_${ key }`]: value }), {}
  )
);
.as-console-wrapper { min-height: 100%!important; top: 0; }