@@ -51,15 +51,55 @@ var reductio_count = {
51
51
52
52
module . exports = reductio_count ;
53
53
} , { } ] , 3 :[ function ( _dereq_ , module , exports ) {
54
+ var reductio_exception_count = {
55
+ add : function ( a , prior ) {
56
+ var i , curr ;
57
+ return function ( p , v ) {
58
+ if ( prior ) prior ( p , v ) ;
59
+ // Only count++ if the p.values array doesn't contain a(v) or if it's 0.
60
+ i = p . bisect ( p . values , a ( v ) , 0 , p . values . length ) ;
61
+ curr = p . values [ i ] ;
62
+ if ( ( ! curr || curr [ 0 ] !== a ( v ) ) || curr [ 1 ] === 0 ) {
63
+ p . exceptionCount ++ ;
64
+ }
65
+ return p ;
66
+ } ;
67
+ } ,
68
+ remove : function ( a , prior ) {
69
+ var i , curr ;
70
+ return function ( p , v ) {
71
+ if ( prior ) prior ( p , v ) ;
72
+ // Only count-- if the p.values array contains a(v) value of 1.
73
+ i = p . bisect ( p . values , a ( v ) , 0 , p . values . length ) ;
74
+ curr = p . values [ i ] ;
75
+ if ( curr && curr [ 0 ] === a ( v ) && curr [ 1 ] === 1 ) {
76
+ p . exceptionCount -- ;
77
+ }
78
+ return p ;
79
+ } ;
80
+ } ,
81
+ initial : function ( prior ) {
82
+ return function ( p ) {
83
+ p = prior ( p ) ;
84
+ p . exceptionCount = 0 ;
85
+ return p ;
86
+ } ;
87
+ }
88
+ } ;
89
+
90
+ module . exports = reductio_exception_count ;
91
+ } , { } ] , 4 :[ function ( _dereq_ , module , exports ) {
54
92
reductio_count = _dereq_ ( './count.js' ) ;
55
93
reductio_sum = _dereq_ ( './sum.js' ) ;
56
94
reductio_avg = _dereq_ ( './avg.js' ) ;
57
95
reductio_value_count = _dereq_ ( './value-count.js' ) ;
96
+ reductio_exception_count = _dereq_ ( './exception-count.js' ) ;
58
97
59
98
function reductio ( ) {
60
- var order , avg , count , sum , unique_accessor , reduceAdd , reduceRemove , reduceInitial ;
99
+ var order , avg , count , sum , exceptionAccessor , exceptionCount ,
100
+ reduceAdd , reduceRemove , reduceInitial ;
61
101
62
- avg = count = sum = unique_accessor = false ;
102
+ avg = count = sum = unique_accessor = countUniques = false ;
63
103
64
104
reduceAdd = function ( p , v ) { return p ; } ;
65
105
reduceAdd = function ( p , v ) { return p ; } ;
@@ -100,9 +140,23 @@ function reductio() {
100
140
}
101
141
}
102
142
103
- if ( unique_accessor ) {
104
- reduceAdd = reductio_value_count . add ( unique_accessor , reduceAdd ) ;
105
- reduceRemove = reductio_value_count . remove ( unique_accessor , reduceRemove ) ;
143
+ // The unique-only reducers come before the value_count reducers. They need to check if
144
+ // the value is already in the values array on the group. They should only increment/decrement
145
+ // counts if the value not in the array or the count on the value is 0.
146
+ if ( exceptionCount ) {
147
+ if ( ! exceptionAccessor ) {
148
+ console . error ( "You must define an .exception(accessor) to use .exceptionCount(true)." ) ;
149
+ } else {
150
+ reduceAdd = reductio_exception_count . add ( exceptionAccessor , reduceAdd ) ;
151
+ reduceRemove = reductio_exception_count . remove ( exceptionAccessor , reduceRemove ) ;
152
+ reduceInitial = reductio_exception_count . initial ( reduceInitial ) ;
153
+ }
154
+ }
155
+
156
+ // Maintain the values array.
157
+ if ( exceptionAccessor ) {
158
+ reduceAdd = reductio_value_count . add ( exceptionAccessor , reduceAdd ) ;
159
+ reduceRemove = reductio_value_count . remove ( exceptionAccessor , reduceRemove ) ;
106
160
reduceInitial = reductio_value_count . initial ( reduceInitial ) ;
107
161
}
108
162
}
@@ -131,17 +185,23 @@ function reductio() {
131
185
return my ;
132
186
} ;
133
187
134
- my . uniques = function ( value ) {
135
- if ( ! arguments . length ) return unique_accessor ;
136
- unique_accessor = value ;
188
+ my . exception = function ( value ) {
189
+ if ( ! arguments . length ) return exceptionAccessor ;
190
+ exceptionAccessor = value ;
191
+ return my ;
192
+ } ;
193
+
194
+ my . exceptionCount = function ( value ) {
195
+ if ( ! arguments . length ) return exceptionCount ;
196
+ exceptionCount = value ;
137
197
return my ;
138
198
} ;
139
199
140
200
return my ;
141
201
}
142
202
143
203
module . exports = reductio ;
144
- } , { "./avg.js" :1 , "./count.js" :2 , "./sum.js" :4 , "./value-count.js" :5 } ] , 4 :[ function ( _dereq_ , module , exports ) {
204
+ } , { "./avg.js" :1 , "./count.js" :2 , "./exception-count.js" : 3 , "./ sum.js" :5 , "./value-count.js" :6 } ] , 5 :[ function ( _dereq_ , module , exports ) {
145
205
var reductio_sum = {
146
206
add : function ( a , prior ) {
147
207
return function ( p , v ) {
@@ -167,7 +227,7 @@ var reductio_sum = {
167
227
} ;
168
228
169
229
module . exports = reductio_sum ;
170
- } , { } ] , 5 :[ function ( _dereq_ , module , exports ) {
230
+ } , { } ] , 6 :[ function ( _dereq_ , module , exports ) {
171
231
// TODO: Figure out how to use a global crossfilter object. We need to
172
232
// import here because the testing framework doesn't provide global
173
233
// objects. We shouldn't need to require this for use in browser.
@@ -191,6 +251,7 @@ var reductio_value_count = {
191
251
} ;
192
252
} ,
193
253
remove : function ( a , prior ) {
254
+ var i ;
194
255
return function ( p , v ) {
195
256
if ( prior ) prior ( p , v ) ;
196
257
i = p . bisect ( p . values , a ( v ) , 0 , p . values . length ) ;
@@ -211,6 +272,6 @@ var reductio_value_count = {
211
272
} ;
212
273
213
274
module . exports = reductio_value_count ;
214
- } , { } ] } , { } , [ 3 ] )
215
- ( 3 )
275
+ } , { } ] } , { } , [ 4 ] )
276
+ ( 4 )
216
277
} ) ;
0 commit comments