在自定义reduce函数中,如何传递其他变量来访问特定的数组值?

时间:2014-09-14 13:11:54

标签: crossfilter

我正在使用自定义缩减功能来平均值。我的问题是我的所有数据当前都在一个数组中,当我传入v时,它会传入整个数组。我需要访问v的特定索引,以便我可以聚合数据,但我遇到了问题。

var curIndex = 1;
function DefineGroups(dimension, dLen) {
    var groups = [];
    curIndex = 1;
    for(var h = 0; h < dLen-3; h++) {
        groups[h] = dimension.group().reduce(SetReduceAdd, SetReduceSub, SetReduceBase);
        curIndex++;
    }
    groups[groups.length] = dimension.group().reduce(SetReduceAdd, SetReduceSub, SetReduceBase);
    curIndex++;
    groups[groups.length] = dimension.group().reduce(SetReduceAdd, SetReduceSub, SetReduceBase);
    return groups;
}

function SetReduceAdd(p, v) {
    p.timestamps += 1;
    p.sum += v[curIndex];
    p.total = p.sum / p.timestamps;
    return p;
}

function SetReduceSub(p, v) {
    p.timestamps -= 1;
    p.sum -= v[curIndex];
    p.total = p.timestamps ? p.sum / p.timestamps : 0
    return p;
}

function SetReduceBase() {
    return {timestamps: 0, sum: 0.0, total: 0.0};
}

问题在于,当这些函数实际被调用时,curIndex已经改变,但是我并不确定如何传递curIndex以便它可以被引用为本地实例变量而不是全局变量。我当前实现的结果是所有组最终都是彼此的副本,即数组中的最终数据集。

我尝试查看基本reduce函数的crossfilter代码,但是我不知道如何更改它以反映我需要完成的工作,因为传入的Add / Remove参数似乎已设置。

关于这个问题的任何想法都会很棒,提前谢谢。

1 个答案:

答案 0 :(得分:1)

我认为你遇到了与here完全相同的问题,答案与戈登相同,我相信。

具体来说,您需要将范围包含在内,如

function buildReduce(index) {
  return function(p, v) {
      p.timestamps += 1;
      p.sum += v[index];
      p.total = p.sum / p.timestamps;
      return p;
  };
}

然后建立像

这样的群组
groups[h] = dimension.group().reduce(buildReduce(curIndex), ...)

这将确保创建的每个组都使用curIndex在创建组时所具有的值。

关于这里发生的事情的说明:

'buildReduce'是一个函数,它接受参数'index'并返回一个在内部使用'index'值的新函数。每次调用'buildReduce'时,它都会返回一个特定于该参数值的 new 函数。在调用'buildReduce'之后,变量'index'存在的唯一位置是'buildReduce'返回的函数。

'buildReduce'返回的那个函数被不同的人称为不同的东西。我叫它们关闭。以下是一系列示例的指南:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures