几个星期前I asked a question关于如何重新安排数据结构并收到此解决方案:
var data = [{ timeline_map: { "2017-05-06": 770, "2017-05-07": 760, "2017-05-08": 1250 } }, { timeline_map: { "2017-05-06": 590, "2017-05-07": 210, "2017-05-08": 300 } }, { timeline_map: { "2017-05-06": 890, "2017-05-07": 2200, "2017-05-08": 1032 } }],
grouped = data.reduce(function (hash) {
return function (r, o) {
Object.keys(o.timeline_map).forEach(function (k) {
if (!hash[k]) {
hash[k] = [k];
r.push(hash[k]);
}
hash[k].push(o.timeline_map[k]);
});
return r;
};
}(Object.create(null)), []);
console.log(grouped);
然而再看一遍,我并不完全确定这是如何运作的 我没有看到过在reduce之前返回一个函数的概念。显然它有效,所以必须有一些原因,但我想澄清一下。
reduce
“这个应用程序中返回一个函数”?答案 0 :(得分:4)
基本上它是一个哈希表的闭包,其值为真正的空对象。
grouped = data.reduce(function (hash) {
return function (r, o) {
// ...
};
}(Object.create(null)), []);
它使用immediately-invoked function expression (IIFE)作为变量hash
,其范围在回调范围内。
function (hash) {
return function (r, o) {
// ...
};
}(Object.create(null))
答案 1 :(得分:3)
不幸的是,这个答案非常神秘。它应该是:
var data = [{ timeline_map: { "2017-05-06": 770, "2017-05-07": 760, "2017-05-08": 1250 } }, { timeline_map: { "2017-05-06": 590, "2017-05-07": 210, "2017-05-08": 300 } }, { timeline_map: { "2017-05-06": 890, "2017-05-07": 2200, "2017-05-08": 1032 } }];
function group(data) {
const hash = {};
return data.reduce(function(r, o) {
Object.keys(o.timeline_map).forEach(function (k) {
if (!hash[k]) {
hash[k] = [k];
r.push(hash[k]);
}
hash[k].push(o.timeline_map[k]);
});
return r;
}, []);
}
console.log(group(data));
提供的解决方案涉及一种不明智的尝试,以避免通过将其作为参数的自调用函数来分配hash
对象。
答案 2 :(得分:0)
实际上你的函数reduce
会在你调用它而不是传递时立即执行,并返回一个回调,传递给reduce
,然后用该回调调用.reduce(function(hash){...}, []) //meant passing the callback
.reduce(function(hash){...}**(Object.create(null))**, []) //meant executing the callback
,简单。
修改强>
function someFn(hash) {return 10}
.reduce(someFn("abc"))
所以如果
.reduce
这意味着10
会被someFn
调用吗?因为10
将首先调用,它将返回someFn
。同样如果reduce
返回回调怎么办?将使用该回调作为参数调用someFn
。所以这里的情况与你的情况相同,只是不同的是函数{{1}}不是先前创建的,它是立即创建和调用的。 (如果你不知道立即调用函数的概念)