我已经为我正在进行的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
\* --------------------------- */
似乎应该是通过一些过滤,分组或减少策略来获得这种结果的方法,但是在花费方式过多时间尝试之后,我还没有能够想出一个。我见过的所有使用多个维度的例子都会产生聚合,但这不是我需要的。我需要价值观。有没有更好的方法来解决这个问题?
答案 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);
});
});