D3.js 如何操作crossfilter中的reduce函数来创建特定的数组/对象结构?

D3.js 如何操作crossfilter中的reduce函数来创建特定的数组/对象结构?,d3.js,reduce,crossfilter,D3.js,Reduce,Crossfilter,我正在使用交叉滤波器,并在reduce函数之后寻找特定的输出: var ndx = crossfilter(data); var alDim = ndx.dimension(function(d) { return d.al_code_unique; }); var seatsPaxAirline = alDim.group().reduce( function(a, d) { a.seats += d.seats;

我正在使用交叉滤波器,并在reduce函数之后寻找特定的输出:

var ndx = crossfilter(data);     
var alDim = ndx.dimension(function(d) { return d.al_code_unique; });
var seatsPaxAirline = alDim.group().reduce(
            function(a, d) {
                a.seats += d.seats;
                a.pax += d.pax;
                return a;
            },
            function(a, d) {
                a.seats -= d.seats;
                a.pax -= d.pax;
                return a;
            },
            function() {
                return  {seats:0, pax:0 }; }
            ).top(100);
[
 {key: "5Y", value: [ {name: "pax", value: 60}, {name: "seats", value: 100}},
 {key: "4Y", value: [ {name: "pax", value: 50}, {name: "seats", value: 90}},
 {key: "3Y", value: [ {name: "pax", value: 40}, {name: "seats", value: 80}},
]
seatsPaxAirline现在是一个对象数组,如下所示:

[
{key: "5Y", value: {pax: 60, seats: 100}},
{key: "4Y", value: {pax: 50, seats: 90}},
{key: "3Y", value: {pax: 40, seats: 80}}
]
但我确实需要crossfilter reduce函数的以下输出:

var ndx = crossfilter(data);     
var alDim = ndx.dimension(function(d) { return d.al_code_unique; });
var seatsPaxAirline = alDim.group().reduce(
            function(a, d) {
                a.seats += d.seats;
                a.pax += d.pax;
                return a;
            },
            function(a, d) {
                a.seats -= d.seats;
                a.pax -= d.pax;
                return a;
            },
            function() {
                return  {seats:0, pax:0 }; }
            ).top(100);
[
 {key: "5Y", value: [ {name: "pax", value: 60}, {name: "seats", value: 100}},
 {key: "4Y", value: [ {name: "pax", value: 50}, {name: "seats", value: 90}},
 {key: "3Y", value: [ {name: "pax", value: 40}, {name: "seats", value: 80}},
]

我觉得这只是一个以某种方式改变reduce函数的问题,但不幸的是我没有任何线索。有人能帮我吗?提前谢谢

据我所知,您的输入格式类似于:

var seatsPaxAirline = 
    [{key: "5Y", value: {pax: 60, seats: 100}},
     {key: "5Y", value: {pax: 40, seats: 100}},
     {key: "3Y", value: {pax: 30, seats: 100}},
     {key: "2Y", value: {pax: 70, seats: 100}},
     {key: "4Y", value: {pax: 50, seats: 100}},
     {key: "1Y", value: {pax: 45, seats: 100}},
     {key: "2Y", value: {pax: 50, seats: 100}},
     {key: "5Y", value: {pax: 60, seats: 100}},
     {key: "5Y", value: {pax: 65, seats: 100}},
     {key: "5Y", value: {pax: 55, seats: 100}}
     ];
并且,您希望根据元素的键值对元素进行分组,如:

{
    "5Y": [{"key": "5Y", "value": {"pax": 60, "seats": 100}},
           {"key": "5Y", "value": {"pax": 40, "seats": 100}}, 
           {"key": "5Y", "value": {"pax": 60, "seats": 100}}, 
           {"key": "5Y", "value": {"pax": 65, "seats": 100}}, 
           {"key": "5Y", "value": {"pax": 55, "seats": 100}}],
    "3Y": [{"key": "3Y", "value": {"pax": 30, "seats": 100}}],
    "2Y": [{"key": "2Y", "value": {"pax": 70, "seats": 100}},
           {"key": "2Y", "value": {"pax": 50, "seats": 100}}],
    "4Y": [{"key": "4Y", "value": {"pax": 50, "seats": 100}}],
    "1Y": [{"key": "1Y", "value": {"pax": 45, "seats": 100}}]
}
如果这就是您希望使用D3实现的目标,那么这就是实现的方法:

d3.nest().key(function(d){return d.key}).map(seatsPaxAirline);


编辑: 我相信您提供的示例对象的格式不正确。但是,如果您修改我提供的代码,如下所示:

var output = d3.nest().key(function(d){return d.key}).map(seatsPaxAirline);
d3.entries(d3.entries(output).forEach(function(d,i){
  d.value.forEach(function(o,j){ 
    delete o["key"];
    d.value[j] = d3.entries(o.value);
  });
}));
output = d3.entries(output);
您将获得的输出是:

[{
  "key": "5Y",
  "value": [
    [{"key": "pax","value": 60}, {"key": "seats","value": 100}],
    [{"key": "pax","value": 40}, {"key": "seats","value": 100}],
    [{"key": "pax","value": 60}, {"key": "seats","value": 100}],
    [{"key": "pax","value": 65}, {"key": "seats","value": 100}],
    [{"key": "pax","value": 55}, {"key": "seats","value": 100}]
  ]
}, {
  "key": "3Y",
  "value": [
    [{"key": "pax","value": 30}, {"key": "seats","value": 100}]
  ]
}, {
  "key": "2Y",
  "value": [
    [{"key": "pax","value": 70}, {"key": "seats","value": 100}],
    [{"key": "pax","value": 50}, {"key": "seats","value": 100}]
  ]
}, {
  "key": "4Y",
  "value": [
    [{"key": "pax","value": 50}, {"key": "seats","value": 100}]
  ]
}, {
  "key": "1Y",
  "value": [
    [{"key": "pax","value": 45}, {"key": "seats","value": 100}]
  ]
}]
这是我能得到的最接近所需数据结构的数据。看看这对你是否有用


PS:我意识到这并不是最有效的解决方案,但这和我的D3一样好。如果你想愚弄数据结构,考虑使用.

,就我理解的问题而言,你需要改变你的缩减函数,比如::/p>
var seatsPaxAirline = alDim.group().reduce(
            function(a, d) {
                a[0].value += d.seats;
                a[1].value += d.pax;
                return a;
            },
            function(a, d) {
                a[0].value -= d.seats;
                a[1].value -= d.pax;
                return a;
            },
            function() {
                return  [{name: 'seats', value: 0}, {name: 'pax', value: 0}]; }
            ).top(100);

关键在于如何设置reduceInitial函数,因为这将决定通过reduce的“a”对象的数据结构

对不起,也许我在解释对象/数组结构时有点太短了。我已经在上面作了一些澄清。我不打算如上所述修改交叉滤波器输出。非常感谢您的帮助。很难准确说出您想要什么,因为您的示例不太正确(“paxOnDep”是否应该是“pax”?)。但我想到的问题是:你为什么要这样做?看起来您只是将结果对象重新编码为一个数组,但我不清楚这给您带来了什么。是的,您是对的:paxOnDep表示pax-我在示例中更改了它。这也是事实,我只需要重新编码的结果。原因是我需要对分组的D3行图表使用交叉筛选结果。例如,DC.js不支持这种类型的图表。在创建d3分组图表时,我希望输出的外观允许我具有最大的灵活性。感谢您的承诺和提供的解决方案。在修改了所有内容之后,我意识到我混淆了尺寸和度量,因此你说我的exmaple有点错误是对的。然而,对我来说,这是一个很好的发现。再次感谢。嘿,谢谢,这正是我想要的。这对我将来也有帮助。另外,我注意到您使用的是top(100),使用这种类型的数组缩减时,它的行为可能不符合预期。例如,要按座位排序,您可能需要如下设置自定义排序函数:函数orderValue(p){return p[0].value;}var seatsPaxAirline=alDim.group().reduce(…).order(orderValue).top(100)