为什么在`array#reduce`中返回一个函数而不是只传递一个函数

时间:2017-07-16 18:14:10

标签: javascript ecmascript-6 reduce

几个星期前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“这个应用程序中返回一个函数”?

3 个答案:

答案 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}}不是先前创建的,它是立即创建和调用的。 (如果你不知道立即调用函数的概念)