(rows: readonly T[], agg: AggregateIrExpression)
| 170 | } |
| 171 | |
| 172 | const computeAggregateValue = <T extends FieldValues>(rows: readonly T[], agg: AggregateIrExpression): unknown => { |
| 173 | switch (agg._tag) { |
| 174 | case "agg-count": |
| 175 | return rows.length |
| 176 | case "agg-count-when": { |
| 177 | const filter = agg.filter |
| 178 | const matches = filter.length === 0 ? () => true : (row: unknown) => codeFilter3_(filter, row) |
| 179 | return rows.filter((row) => matches(row)).length |
| 180 | } |
| 181 | case "agg-sum": |
| 182 | return rows.reduce<number>((acc, row) => { |
| 183 | const v = get(row, agg.field) |
| 184 | return acc + (typeof v === "number" ? v : Number(v) || 0) |
| 185 | }, 0) |
| 186 | case "agg-min": { |
| 187 | let min: unknown = undefined |
| 188 | for (const row of rows) { |
| 189 | const v = get(row, agg.field) |
| 190 | if (v == null) continue |
| 191 | if (min === undefined || v < (min as any)) min = v |
| 192 | } |
| 193 | return min ?? null |
| 194 | } |
| 195 | case "agg-max": { |
| 196 | let max: unknown = undefined |
| 197 | for (const row of rows) { |
| 198 | const v = get(row, agg.field) |
| 199 | if (v == null) continue |
| 200 | if (max === undefined || v > (max as any)) max = v |
| 201 | } |
| 202 | return max ?? null |
| 203 | } |
| 204 | default: |
| 205 | return assertUnreachable(agg) |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | export function memFilter<T extends FieldValues, U extends keyof T = never>(f: FilterArgs<T, U>) { |
| 210 | type M = U extends undefined ? T : Pick<T, U> |
no test coverage detected
searching dependent graphs…