|
| 1 | +import { factory } from '../../utils/factory.js' |
| 2 | +import { createMatAlgo03xDSf } from '../../type/matrix/utils/matAlgo03xDSf.js' |
| 3 | +import { createMatAlgo14xDs } from '../../type/matrix/utils/matAlgo14xDs.js' |
| 4 | +import { createMatAlgo13xDD } from '../../type/matrix/utils/matAlgo13xDD.js' |
| 5 | +import { DimensionError } from '../../error/DimensionError.js' |
| 6 | + |
| 7 | +const name = 'nullish' |
| 8 | +const dependencies = ['typed', 'matrix', 'size', 'flatten', 'deepEqual'] |
| 9 | + |
| 10 | +export const createNullish = /* #__PURE__ */ factory( |
| 11 | + name, |
| 12 | + dependencies, |
| 13 | + ({ typed, matrix, size, flatten, deepEqual }) => { |
| 14 | + const matAlgo03xDSf = createMatAlgo03xDSf({ typed }) |
| 15 | + const matAlgo14xDs = createMatAlgo14xDs({ typed }) |
| 16 | + const matAlgo13xDD = createMatAlgo13xDD({ typed }) |
| 17 | + |
| 18 | + /** |
| 19 | + * Nullish coalescing operator (??). Returns the right-hand side operand |
| 20 | + * when the left-hand side operand is null or undefined, and otherwise |
| 21 | + * returns the left-hand side operand. |
| 22 | + * |
| 23 | + * For matrices, the function is evaluated element wise. |
| 24 | + * |
| 25 | + * Syntax: |
| 26 | + * |
| 27 | + * math.nullish(x, y) |
| 28 | + * |
| 29 | + * Examples: |
| 30 | + * |
| 31 | + * math.nullish(null, 42) // returns 42 |
| 32 | + * math.nullish(undefined, 42) // returns 42 |
| 33 | + * math.nullish(0, 42) // returns 0 |
| 34 | + * math.nullish(false, 42) // returns false |
| 35 | + * math.nullish('', 42) // returns '' |
| 36 | + * |
| 37 | + * // Object property access with fallback |
| 38 | + * const obj = {foo: 7, bar: 3} |
| 39 | + * math.nullish(obj.baz, 0) // returns 0 |
| 40 | + * |
| 41 | + * See also: |
| 42 | + * |
| 43 | + * and, or, not |
| 44 | + * |
| 45 | + * @param {*} x First value to check |
| 46 | + * @param {*} y Fallback value |
| 47 | + * @return {*} Returns y when x is null or undefined, otherwise returns x |
| 48 | + */ |
| 49 | + |
| 50 | + return typed( |
| 51 | + name, |
| 52 | + { |
| 53 | + // Scalar and SparseMatrix-first short-circuit handlers |
| 54 | + 'number|bigint|Complex|BigNumber|Fraction|Unit|string|boolean|SparseMatrix, any': (x, _y) => x, |
| 55 | + 'null, any': (_x, y) => y, |
| 56 | + 'undefined, any': (_x, y) => y, |
| 57 | + |
| 58 | + // SparseMatrix-first with collection RHS: enforce exact shape match |
| 59 | + 'SparseMatrix, Array | Matrix': (x, y) => { |
| 60 | + const sx = flatten(size(x).valueOf()) // work around #3529/#3530 |
| 61 | + const sy = flatten(size(y).valueOf()) |
| 62 | + if (deepEqual(sx, sy)) return x |
| 63 | + throw new DimensionError(sx, sy) |
| 64 | + }, |
| 65 | + |
| 66 | + // DenseMatrix-first handlers (no broadcasting between collections) |
| 67 | + 'DenseMatrix, DenseMatrix': typed.referToSelf(self => (x, y) => matAlgo13xDD(x, y, self)), |
| 68 | + 'DenseMatrix, SparseMatrix': typed.referToSelf(self => (x, y) => matAlgo03xDSf(x, y, self, false)), |
| 69 | + 'DenseMatrix, Array': typed.referToSelf(self => (x, y) => matAlgo13xDD(x, matrix(y), self)), |
| 70 | + 'DenseMatrix, any': typed.referToSelf(self => (x, y) => matAlgo14xDs(x, y, self, false)), |
| 71 | + |
| 72 | + // Array-first handlers (bridge via matrix() where needed) |
| 73 | + 'Array, Array': typed.referToSelf(self => (x, y) => matAlgo13xDD(matrix(x), matrix(y), self).valueOf()), |
| 74 | + 'Array, DenseMatrix': typed.referToSelf(self => (x, y) => matAlgo13xDD(matrix(x), y, self)), |
| 75 | + 'Array, SparseMatrix': typed.referToSelf(self => (x, y) => matAlgo03xDSf(matrix(x), y, self, false)), |
| 76 | + 'Array, any': typed.referToSelf(self => (x, y) => matAlgo14xDs(matrix(x), y, self, false).valueOf()) |
| 77 | + } |
| 78 | + ) |
| 79 | + } |
| 80 | +) |
0 commit comments