Javascript 使用交叉筛选的唯一值的数目

Javascript 使用交叉筛选的唯一值的数目,javascript,multidimensional-array,grouping,crossfilter,Javascript,Multidimensional Array,Grouping,Crossfilter,这里是CrossFilter/JS新手 这个问题非常准确地描述了我试图做的事情,但似乎没有使用交叉过滤器的解决方案: 我和你有数据 var va = [{ date: "2014-10-01", id: "1"}, { date: "2014-10-02", id: "1"}, { date: "2014-10-03", id: "1"}, { date: "2014-10-04", id: "1"}, { date: "2014-10-05", id: "1"}, { date: "2014

这里是CrossFilter/JS新手

这个问题非常准确地描述了我试图做的事情,但似乎没有使用交叉过滤器的解决方案:

我和你有数据

var va = [{
date: "2014-10-01",
id: "1"},
{
date: "2014-10-02",
id: "1"},
{
date: "2014-10-03",
id: "1"},
{
date: "2014-10-04",
id: "1"},
{
date: "2014-10-05",
id: "1"},
{
date: "2014-10-01",
id: "2"},
{
date: "2014-10-02",
id: "2"},
{
date: "2014-10-03",
id: "2"},
{
date: "2014-10-04",
id: "1"},
{
date: "2014-10-01",
id: "3"},
{
date: "2014-10-02",
id: "3"},
{
date: "2014-10-03",
id: "1"},
{
date: "2014-10-01",
id: "4"},
{
date: "2014-10-02",
id: "1"},
{
date: "2014-10-01",
id: "5"}
}
我正在尝试从中获取每个日期的唯一id数。我想按日期分组,基本上有一个特定日期的唯一id的计数:

"2014-10-01" - 5
"2014-10-02" - 3
"2014-10-03" - 2
"2014-10-04" - 1
"2014-10-05" - 1
目前,我正试图遵循这个问题的答案

要执行以下操作:

//Create a Crossfilter instance
var ndx = crossfilter(va);

//Define dimensions
var date_dim = ndx.dimension(function(d) {
    return d["date"]; });

//total number of ids per date
var num_ids_by_date = date_dim.group();

//unique number of ids per date
var num_uniq_ids_by_date = date_dim
    .group()
    .reduce(
        function (p, d) {
            if(d.id in p.ids){
            }
            else{
                p.ids[d.id] = 1;
            }
            return p;
        },

        function (p, d) {
            p.ids[d.id]--;
            if(p.ids[d.id] === 0){
                delete p.ids[d.id];
            }
            return p;
        },

        function () {
            return {ids: {}};
        })
//Create a Crossfilter instance
var ndx = crossfilter(va);

//Define dimensions
var date_dim = ndx.dimension(function(d) {
    return d["date"]; });

var num_unique_ids_by_date = date_dim
    .group()
    .reduce(
        function (p, d) {
            if(d.id in p.ids){
                p.ids[d.id] += 1
            }
            else{
                p.ids[d.id] = 1;
                p.id_count++;
            }
            return p;
        },

        function (p, d) {
            p.ids[d.id]--;
            if(p.ids[d.id] === 0){
                delete p.ids[d.id];
                p.id_count--;
            }
            return p;
        },

        function () {
                return {ids: {},
                id_count: 0};
            });
当我查看
num\u uniq\u ids\u by\u date
对象并调用
num\u uniq\u ids\u by\u date.reduceCount().top(1)
,它的输出似乎与
num\u ids\u by\u date.top(1)
相同

所以,我似乎仍然没有得到我想要的,并且已经被难住了一段时间


有什么建议吗?提前谢谢

好吧,我能拿到它

我最终做了以下几点:

//Create a Crossfilter instance
var ndx = crossfilter(va);

//Define dimensions
var date_dim = ndx.dimension(function(d) {
    return d["date"]; });

//total number of ids per date
var num_ids_by_date = date_dim.group();

//unique number of ids per date
var num_uniq_ids_by_date = date_dim
    .group()
    .reduce(
        function (p, d) {
            if(d.id in p.ids){
            }
            else{
                p.ids[d.id] = 1;
            }
            return p;
        },

        function (p, d) {
            p.ids[d.id]--;
            if(p.ids[d.id] === 0){
                delete p.ids[d.id];
            }
            return p;
        },

        function () {
            return {ids: {}};
        })
//Create a Crossfilter instance
var ndx = crossfilter(va);

//Define dimensions
var date_dim = ndx.dimension(function(d) {
    return d["date"]; });

var num_unique_ids_by_date = date_dim
    .group()
    .reduce(
        function (p, d) {
            if(d.id in p.ids){
                p.ids[d.id] += 1
            }
            else{
                p.ids[d.id] = 1;
                p.id_count++;
            }
            return p;
        },

        function (p, d) {
            p.ids[d.id]--;
            if(p.ids[d.id] === 0){
                delete p.ids[d.id];
                p.id_count--;
            }
            return p;
        },

        function () {
                return {ids: {},
                id_count: 0};
            });
这将为我提供唯一id的总数以及每个id的总出现次数

然后,当我想使用dc.js在条形图中显示它时,我继续使用下面的代码

var minDate = date_dim.bottom(1)[0]["date"];
var maxDate = date_dim.top(1)[0]["date"];

var timeChart = dc.barChart("#time-chart");

timeChart
    .width(1500)
    .height(400)
    .margins({top: 10, right: 50, bottom: 30, left: 50})
    .dimension(date_dim)
    .group(num_unique_ids_by_date)
    .valueAccessor(function (d) {
        return d.value.id_count;
    })
    .transitionDuration(500)
    .x(d3.time.scale().domain([minDate, maxDate]))
    .elasticY(true)
    .elasticX(true)
    .xAxisLabel("Year")
    .yAxis();

dc.renderAll();

似乎您没有增加add上的计数器,这将给您带来问题。如果你把一个有效的例子放在一起,就更容易诊断问题。你也可以使用像ReduceTio这样的库,它支持这一点:(插入我自己的库,对不起)谢谢Ethan的回复。我不在add上增加计数器的原因是,我并不完全关心每个特定id的数量,我只想要唯一id的数量。另外,谢谢图书馆的建议,我一定会去看看的。如果可能的话,我想在我还在学习的时候暂时把它保留在交叉过滤器库中:)如果你不在添加时递增,但在删除时递减(你正在这样做),你会很快进入一个不一致的状态。不过我没看到你真正的问题。调用
num\u uniq\u ids\u by\u date.reduceCount()
将清除所有自定义组减缩器。只需按日期调用
num\u uniq\u ids\u.top(1)
.Oops,这是我的一个错误-感谢您指出这一点。谢谢你的建议!事实上我能得到它。我一定会补充我的答案。