diff --git a/src/type/unit/Unit.js b/src/type/unit/Unit.js index 87498385b0..2943ebada7 100644 --- a/src/type/unit/Unit.js +++ b/src/type/unit/Unit.js @@ -1,4 +1,4 @@ -import { isComplex, isUnit, typeOf } from '../../utils/is.js' +import { isComplex, isMatrix, isUnit, typeOf } from '../../utils/is.js' import { factory } from '../../utils/factory.js' import { memoize } from '../../utils/function.js' import { endsWith } from '../../utils/string.js' @@ -1320,6 +1320,14 @@ export const createUnitClass = /* #__PURE__ */ factory(name, dependencies, ({ * @return {Array} An array of units. */ Unit.prototype.splitUnit = function (parts) { + // When invoked as a method in the expression parser + // (e.g. `(1 m).splitUnit([ft, in])`), `parts` is passed as a Matrix rather + // than a plain Array. Normalize it to an Array so the iteration below works + // in both cases. + if (isMatrix(parts)) { + parts = parts.toArray() + } + let x = this.clone() const ret = [] for (let i = 0; i < parts.length; i++) { diff --git a/test/unit-tests/type/unit/function/splitUnit.test.js b/test/unit-tests/type/unit/function/splitUnit.test.js index aad0b20833..078cb65cff 100644 --- a/test/unit-tests/type/unit/function/splitUnit.test.js +++ b/test/unit-tests/type/unit/function/splitUnit.test.js @@ -11,4 +11,13 @@ describe('splitUnit', function () { assert.strictEqual(math.evaluate('splitUnit(1 m, [ft, in])').toString(), '3 ft,3.3700787401574765 in') }) + + it('should split a unit when parts are passed as a Matrix', function () { + // when splitUnit is called as a method in the expression parser, the parts + // are passed as a Matrix rather than an Array (see #3644) + assert.strictEqual(splitUnit(new Unit(1, 'm'), math.matrix(['ft', 'in'])).toString(), '3 ft,3.3700787401574765 in') + + assert.strictEqual(math.evaluate('(1 m).splitUnit([ft, in])').toString(), '3 ft,3.3700787401574765 in') + assert.strictEqual(math.evaluate('(1 m).splitUnit(["ft", "in"])').toString(), '3 ft,3.3700787401574765 in') + }) })