Skip to content

Commit 7126482

Browse files
committed
test for empty outside the reducers
(this also avoids looking up I[-1] (last) or I[0] with non-existent indices)
1 parent 1f46c3f commit 7126482

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

src/transforms/group.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,13 @@ export function maybeReduce(reduce, value) {
136136
if (reduce && typeof reduce.reduce === "function") return reduce;
137137
if (typeof reduce === "function") return reduceFunction(reduce);
138138
switch ((reduce + "").toLowerCase()) {
139-
case "first": return reduceFirst;
140-
case "last": return reduceLast;
141-
case "count": return reduceCount;
142-
case "distinct": return reduceDistinct;
143-
case "sum": return value == null ? reduceCount : reduceSum;
144-
case "proportion": return reduceProportion(value, "data");
145-
case "proportion-facet": return reduceProportion(value, "facet");
139+
case "first": return emptyReduce(reduceFirst);
140+
case "last": return emptyReduce(reduceLast);
141+
case "count": return emptyReduce(reduceCount);
142+
case "distinct": return emptyReduce(reduceDistinct);
143+
case "sum": return emptyReduce(value == null ? reduceCount : reduceSum);
144+
case "proportion": return emptyReduce(reduceProportion(value, "data"));
145+
case "proportion-facet": return emptyReduce(reduceProportion(value, "facet"));
146146
case "deviation": return reduceAccessor(deviation);
147147
case "min": return reduceAccessor(min);
148148
case "max": return reduceAccessor(max);
@@ -154,6 +154,12 @@ export function maybeReduce(reduce, value) {
154154
throw new Error("invalid reduce");
155155
}
156156

157+
function emptyReduce(reducer) {
158+
const {reduce} = reducer;
159+
reducer.reduce = (I, X, basis) => I.length ? reduce(I, X, basis) : NaN;
160+
return reducer;
161+
}
162+
157163
export function maybeSubgroup(outputs, Z, F, S) {
158164
return firstof(
159165
outputs.some(o => o.name === "z") ? undefined : Z,
@@ -199,14 +205,13 @@ const reduceLast = {
199205
const reduceCount = {
200206
label: "Frequency",
201207
reduce(I) {
202-
return I.length || NaN;
208+
return I.length;
203209
}
204210
};
205211

206212
const reduceDistinct = {
207213
label: "Distinct",
208214
reduce: (I, X) => {
209-
if (I.length === 0) return NaN;
210215
const s = new InternSet();
211216
for (const i of I) s.add(X[i]);
212217
return s.size;
@@ -217,6 +222,6 @@ const reduceSum = reduceAccessor(sum);
217222

218223
function reduceProportion(value, scope) {
219224
return value == null
220-
? {scope, label: "Frequency", reduce: (I, V, basis = 1) => I.length ? I.length / basis : NaN}
221-
: {scope, reduce: (I, V, basis = 1) => I.length ? sum(I, i => V[i]) / basis : NaN};
225+
? {scope, label: "Frequency", reduce: (I, V, basis = 1) => I.length / basis}
226+
: {scope, reduce: (I, V, basis = 1) => sum(I, i => V[i]) / basis};
222227
}

0 commit comments

Comments
 (0)