有没有一种好方法可以使用crossfilter查询唯一值的多个维度,而不是聚合?

时间:2014-04-29 05:33:03

标签: crossfilter

我已经为我正在进行的dc.js项目中的一系列数据加载到了crossfilter中。当然,我的一些列中有重复的值,我希望能够在一列中找到与另一列中的重复值对应的唯一值列表。下面的样本数据可能更清楚地说明了这一点。

var data = [
    { state: "WA", city: "Seattle",  data: "a" },
    { state: "WA", city: "Seattle",  data: "b" },
    { state: "WA", city: "Tacoma",   data: "c" },
    { state: "OR", city: "Portland", data: "d" },
    { state: "OR", city: "Bend",     data: "e" },
    { state: "OR", city: "Bend",     data: "f" }
];

我希望能够对特定州进行过滤,然后找到该州的唯一城市列表。所以,如果输入是" WA",我想回到一个包含"西雅图"和#34;塔科马"。下面的代码实际上确实如此(并且还提供了计数,但我真的不关心那些)但是必须创建第二个crossfilter对象对我来说非常笨拙。我也不知道性能,因为我最终需要多次迭代这一次,每个状态一次。

var Ndx = crossfilter(data);
var stateDim = Ndx.dimension(function (d) { return d.state; });
var cityDim = Ndx.dimension(function (d) { return d.city; });

var stateFilter = stateDim.filter("WA");
var stateRows = stateFilter.top(Infinity);

// It seems like there should be a better way than this.
var cityNdx = crossfilter(stateRows);
var cityDim2 = cityNdx.dimension(function (d) { return d.city; });
var cites = cityDim2.group().top(Infinity);

cites.forEach(function(d) {
    console.log("City: " + d.key + ", Count: " + d.value);
});

/* --------------------------- *\
Log output:

City: Seattle, Count: 2
City: Tacoma, Count: 1

\* --------------------------- */

似乎应该是通过一些过滤,分组或减少策略来获得这种结果的方法,但是在花费方式过多时间尝试之后,我还没有能够想出一个。我见过的所有使用多个维度的例子都会产生聚合,但这不是我需要的。我需要价值观。有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:0)

我使用自定义缩减功能来保存为给定状态显示的所有城市值的数组。以下内容(完全未经测试 - 抱歉)应该有效:

var Ndx = crossfilter(data);
var stateDim = Ndx.dimension(function (d) { return d.state; });
var stateGroup = stateDim.group().reduce(
  function(p, v) {
    p.count++;
    if(p.uniques.indexOf(v.city) === -1) p.uniques.push(v.city);
  },
  function(p, v) {
    p.count--;
    // Note: uniques are not filtered. You need to use a map and keep
    // count of uniques to have uniques that match your current filter
  },
  function() {
    return { count: 0, uniques: [] };
  }
);

stateGroup.top(Infinity).forEach( function(g) {
  console.log("State " + g.key + " has count " + g.value.count);
  console.log("Unique cities in " + g.key + ":");

  g.value.uniques.forEach(function (c) {
    console.log(c);
  });
});