unit-system
v1.13.0
Published
A library for defining unit systems and performing unit-safe calculations
Downloads
5
Maintainers
Readme
unit-system
ΜΕΤΡΩ ΧΡΩ
Use the measure
A library for defining unit systems and performing unit-safe calculations
Demo
const { createUnitSystem, conversion } = require('unit-system');
const { createUnit, m, equal, add } = createUnitSystem();
const inch = createUnit('inch');
const yard = createUnit('yard', {
alias: ['yd', 'yard', 'yards'],
});
const foot = createUnit('foot', {
alias: 'feet',
convert: {
to: [yard, conversion.divideBy(3)],
from: [inch, conversion.divideBy(12)],
},
});
const twoYards = add(m`1 yard`, m`3 feet`);
equal(twoYards, m(72, inch)) === true;
Documentation
createUnitSystem(units)
Most uses of unit-system
start with createUnitSystem()
.
const { createUnitSystem } = require('unit-system');
const { createUnit, m, convert, system } = createUnitSystem();
createUnit(name, options)
Creates a new Unit
and automatically registers it with system
(the UnitSystem
created by createUnitSystem
).
const inch = createUnit('inch', { alias: 'inches' });
const foot = createUnit('foot', {
convert: {
from: [inch, conversion.divideBy(12)],
},
});
m(number, unit)
Shorthand function for creating new Measurement
instances. If a unit is defined with an alias, that alias can be used instead of passing in the unit. (see UnitSystem#measure()
for details)
m`12 inches`;
convert(measurement, unit)
Given a Measurement
and a Unit
, convert(measurement, unit)
will attempt to convert that measurement to the given unit. (see UnitSystem#convert()
for details)
convert(m`24 inches`, foot);
// => new Measurement(2, foot)
system
The UnitSystem
created by createUnitSystem
.
conversion
A collection of converter creators. A converter is an object with forward
and backward
methods, meant for converting between two units.
Converters shouldn't be used directly. Instead, define them when creating a unit, and UnitSystem
will be able to automatically convert for you.
const { conversion } = require('unit-system');
conversion.slopeIntercept(slope, intercept = 0)
Given a slope
and an optional intercept
, produces a converter.
Also exported as: multiplyBy
, times
const celsiusToFahrenheit = conversion.slopeIntercept(9 / 5, 32);
celsiusToFahrenheit.forward(100) === 212;
celsiusToFahrenheit.backward(32) === 0;
conversion.divideBy(divisor)
A special case of multiplyBy
, useful when defining the reverse conversion is clearer.
const feetToInches = conversion.divideBy(12);
feetToInches.forward(3) === 36;
feetToInches.backward(12) === 1;
conversion.twoPoint([x1, y1], [x2, y2])
Given two example points on a line, produces a converter. Useful when a conversion can be more clearly expressed in terms of easily-understood examples.
Also exported as: fromExamples
, byExample
const freezing = [0, 32];
const boiling = [100, 212];
const celsiusToFahrenheit = conversion.twoPoint(freezing, boiling);
celsiusToFahrenheit.forward(100) === 212;
celsiusToFahrenheit.backward(32) === 0;
conversion.addConstant(constant)
Given a constant value, produces a converter. A special case of slopeIntercept
where slope
is always 1
.
Also exported as: add
, constant
const celsiusToKelvin = conversion.addConstant(273.15);
celsiusToKelvin.forward(0) === 273.15;
celsiusToKelvin.backward(-272.15) === 1;
new Unit(name)
The base unit type.
const { Unit } = require('unit-system');
const inch = new Unit('inch');
inch.name === 'inch';
new Measurement(number, unit)
A value type representing a number and its unit.
const { Measurement } = require('unit-system');
const oneInch = new Measurement(1, inch);
oneInch.value === 1;
oneInch.unit === inch;
new UnitSystem(units)
A collection of units. Internally tracks aliases for units (used by m
to look up the corresponding unit) and converters.
const { UnitSystem } = require('unit-system');
const myUnitSystem = new UnitSystem([
[inch, { alias: 'inches' }],
[foot, { convert: { from: [inch, conversion.divideBy(12)] } }],
]);
myUnitSystem.getUnitForAlias('inches') === inch;
myUnitSystem.convert(new Measurement(12, inch), foot);
// => new Measurement(1, foot)
.merge(...unitSystems)
Takes one or more other UnitSystem
s and copies this unit into this one.
const mySystem = new UnitSystem([[new Unit('inch'), { alias: 'inches' }]]);
const systemA = new UnitSystem([[new Unit('foot')]]);
const systemB = new UnitSystem([[new Unit('yard')]]);
const systemC = new UnitSystem([[new Unit('mile')]]);
mySystem.merge(systemA, systemB, systemC);
.register(unit, { alias, convert })
Registers the given unit within the system.
const inch = new Unit('inch');
system.register(inch);
If alias
is provided, that unit can now be referenced by that alias.
system.register(inch, { alias: 'inches' });
If convert
is provided, its properties to
and from
are used to register converters between two units.
system.register(inch, {
convert: {
to: [centimeter, multiplyBy(2.54)],
from: [foot, divideBy(12)],
},
});
.registerAll(units)
Like the first argument to new UnitSystem(units)
, registers all the given units.
.addConverter(startUnit, endUnit, converter)
Adds a converter for units that have already been registered.
const inch = new Unit('inch');
const foot = new Unit('foot');
const system = new UnitSystem([[inch], [foot]]);
system.addConverter(inch, foot, divideBy(12));
.getUnitForAlias(alias)
Looks up the corresponding unit for the given alias.
system.getUnitForAlias('inches') === inch;
.convert(measurement, unit|string)
convert
will take the given measurement and attempt to convert it the desired unit. It may take multiple hops to make that happen.
If unit
is a string, convert
will assume it is an alias and will look up the corresponding unit.
Consider a UnitSystem
that defines kilometers, meters, centimeters, inches, feet, and miles:
const kilometer = createUnit('kilometer');
const meter = createUnit('meter', {
convert: {
from: [kilometer, conversion.multiplyBy(1000)],
},
});
const centimeter = createUnit('centimeter', {
convert: {
from: [meter, conversion.multiplyBy(100)],
},
});
const inch = createUnit('inch', {
convert: {
to: [centimeter, conversion.multiplyBy(2.54)],
},
});
const foot = createUnit('foot', {
convert: {
from: [inch, conversion.divideBy(12)],
},
});
const mile = createUnit('mile', {
alias: 'mile',
convert: {
to: [foot, conversion.multiplyBy(5280)],
},
});
It can convert miles to kilometers, even though a converter between those two was never explicitly declared:
const oneMileInKilometers = system.convert(m`1 mile`, kilometer);
oneMileInKilometers.value === 1.609344;
When a multi-step converter is created, it will be cached, to save on the lookup time.
.add(...measurements)
add
will take the given measurements and attempt to add them together, converting them if needed.
Consider a UnitSystem
that defines centimeters, inches, and feet:
const centimeter = createUnit('centimeter');
const inch = createUnit('inch', {
alias: 'inches',
convert: {
to: [centimeter, conversion.multiplyBy(2.54)],
},
});
const foot = createUnit('foot', {
alias: 'feet',
convert: {
from: [inch, conversion.divideBy(12)],
},
});
It can add up several values in each of those units, converting them to the same unit:
const eightFeet = system.add(
m`2 feet`,
m`18 inches`,
m`2 inches`,
m(15.24, centimeter),
m`10 inches`,
m`3 feet`
);
eightFeet.value === 8;
eightFeet.unit === foot;
.subtract(measurement1, measurement2)
subtract
will take the two given measurements and attempt to subtract them, converting them if needed.
Consider a UnitSystem
that defines centimeters and inches:
const centimeter = createUnit('centimeter');
const inch = createUnit('inch', {
alias: 'inches',
convert: {
to: [centimeter, conversion.multiplyBy(2.54)],
},
});
It can subtract two values in either of those units, converting them to the same unit:
const eighteenInches = system.subtract(m`24 inches`, m(15.24, centimeter));
eighteenInches.value === 18;
eighteenInches.unit === inch;
subtract
does not support operating on more than 2 measurements at a time.
.multiply(measurement, ...numbers)
multiply
will take the a measurement and multiply it with one or more numbers. The order of arguments is not important. Only one measurement can be supplied.
const twelveInches = system.multiply(m`4 inches`, 3);
twelveInches.value === 12;
twelveInches.unit === inch;
.divide(measurement, measurement|number)
divide
will take a measurement and divide it by the second argument, returning either another measurement or a number, depending on the type of the second argument.
const fourInches = system.divide(m`12 inches`, 3);
fourInches.value === 4;
fourInches.unit === inch;
system.divide(m`18 inches`, m`6 inches`) === 3;
It will also automatically convert units when dividing two measurements:
system.divide(m`3 feet`, m`18 inches`) === 2;
.equal(measurement, measurement)
equal
will return true
if the two measurements have the same value and unit (after conversion). Otherwise it returns false
.
system.equal(m`12 inches`, m`1 foot`) === true;
.lessThan(measurement, measurement)
lessThan
will return true
if the first measurement is less than the second (after conversion). Otherwise it returns false
.
.lessThanOrEqual(measurement, measurement)
lessThanOrEqual
will return true
if the first measurement is less than or equal to the second (after conversion). Otherwise it returns false
.
.greaterThan(measurement, measurement)
greaterThan
will return true
if the first measurement is greater than the second (after conversion). Otherwise it returns false
.
.greaterThanOrEqual(measurement, measurement)
greaterThanOrEqual
will return true
if the first measurement is greater than or equal to the second (after conversion). Otherwise it returns false
.
.measure(value, unit)
Shorthand function for creating new Measurement
instances. If a unit is defined with an alias, that alias can be used instead of passing in the unit.
// All of these are equivalent to `new Measurement(12, inch)`
system.measure`12 inches`;
system.measure`12inches`;
system.measure`12 ${inch}`;
system.measure`12`.inches;
system.measure(12).inches;
system.measure(12, inch);
measure
is bound to system
(its this
cannot be changed), so it can be "detached" and used as a bare function (but still retain access to your unit system):
const m = system.measure;
m`12 inches`;