属性添加到 array.reduce() 返回对象的顺序



谁能解释为什么最终输出在array.reduce()函数的不同用途中是相同的?

在第一个实例中,样本数组直接缩小,而在第二个实例中,样本阵列首先被反转,然后被缩小。

var array = [{
"Id": "1",
"Week": "2019-01-13"
},
{
"Id": "2",
"Week": "2019-01-20"
},
{
"Id": "3",
"Week": "2019-01-27"
}
];
array.reduce(function (acc, curr) {
acc[curr.Id] = curr.Week;
console.log(acc);
return acc;
}, {});
//Output
/*{ "1": "2019-01-13" }
{ "1": "2019-01-13", "2": "2019-01-20" }
{ "1": "2019-01-13", "2": "2019-01-20", "3": "2019-01-27" }*/
array.reverse().reduce(function (acc, curr) {
acc[curr.Id] = curr.Week;
console.log(acc);
return acc;
}, {});
//Output 
/*{ "3": "2019-01-27" }
{ "2": "2019-01-20", "3": "2019-01-27" }
{ "1": "2019-01-13", "2": "2019-01-20", "3": "2019-01-27" }
*/

我希望输出显示为 { "3": "2019-01-27", "2": "2019-01-20", "1": "2019-01-13" }.

如果我使用非数字键,则两种情况下的reduce函数输出都符合预期(以相同的顺序传递元素)。

正如在注释中已经提到的,在JS中不能保证对象属性顺序,这就是您获得该输出的原因。如果你想让顺序很重要,你需要使用地图作为你的reduce accumulator

Map 对象保存键值对并记住原始对象 键的插入顺序。

说到这里,这里有一些示例代码可以更好地说明它:

var array = [{ "Id": "1", "Week": "2019-01-13" }, { "Id": "2", "Week": "2019-01-20" }, { "Id": "3", "Week": "2019-01-27" } ];
let r1 = array.reduce(function(acc, curr) {
acc.set(curr.Id, curr.Week);
return acc;
}, new Map());
let r2 = array.reverse().reduce(function(acc, curr) {
acc.set(curr.Id, curr.Week);
return acc;
}, new Map());
console.log('r1:')
r1.forEach(x => console.log(x))
console.log('r2:')
r2.forEach(x => console.log(x))
console.log('fromEntries:')
console.log(Object.fromEntries(r1))
console.log(Object.fromEntries(r2))

请注意,当我们循环浏览两个映射(r1&r2)的条目时,顺序是如何不同的。但是还要注意,当您convert映射到对象文字的那一刻,顺序现在是一样的,因为不能保证 JS 道具顺序。

最新更新