问题描述
我正在React中构建一个鸡尾酒配方应用程序,用户应该能够查看各种测量中的剂量单位。
默认情况下,我以“ ml”显示所有值,用户可以选择以“ cl”,“ oz”或“ part”查看。根据用户选择的内容,我需要根据所选的单位度量来转换数量值。
我当前的代码:
dosageData = [
{
"dosageIngredient": "gin","quantity": "30","unit": "ml",},{
"dosageIngredient": "campari",{
"dosageIngredient": "sweet red vermouth",]
调用用户更改单位量度unitHandler()时,传递通过选择为“ cl”,“ ml”,“ oz”,“ part”的选项
const unitHandler = (option) => {
const newDosage = dosageData;
switch (option) {
case "cl":
newDosage.map((item) => {
item.unit = option; //changing the unit value of each item in the array to "cl"
var amount = parseInt(item.quantity);
// amount = [conversion formula]
setDosageData(newDosage);
setToggleUnit(option);
});
break;
case "ml":
newDosage.map((item) => {
item.unit = option;
setDosageData(newDosage);
setToggleUnit(option);
});
break;
case "oz":
...
break;
case "part":
...
break;
default:
Alert.alert("Value not found");
}
};
如果我们以“ cl”选项为例,我设法更改了数组中的单元类型并保存了新数组。 我缺少在数组中转换实际值“数量”的步骤。
如果需要,我同时具有公式的From(toggleUnit)和To(“ option”)参数。
我尝试使用以下库https://www.npmjs.com/package/mathjs,但它仅在“ ml”和“ cl”之间起作用。
是否有更完整的库或现有的JS函数可用。
解决方法
为了在度量单位之间进行转换,在过去的项目中,我编写了以下类,该类定义了一个包含浮点值和相关单位的属性的对象。例如,“ 5盎司”或“ 2加仑”。该类可以通过以下任一方式实例化。
-
let v0 = new ValueUnits( '1 gal' );
//值和单位之间至少间隔一个空格。 -
let v1 = new ValueUnits( 1,'gal' );
该类还实现了toUnits( units )
方法,该方法将对象值转换为传递的units
。例如...
-
v0.toUnits( 'qt' );
...会将v0
值属性转换为美国夸脱。请注意,toUnits( units )
方法的舍入精度为10位数字,因此定义转换等价项的ValueUnits.unitsMap
表还必须包含10位或更多有效数字。否则,如果对同一个ValueUnits
对象执行多个单位转换,则将开始引入小错误。
随后的代码示例定义了ValueUnits
类,然后实例化了“ 1 gal”,将gal-> oz-> ml-> l-> qt-> gal ...转换为
class ValueUnits {
constructor( value,units ) {
let fValue,fUnits;
if ( units ) {
fValue = value;
fUnits = units;
} else {
[ fValue,fUnits ] = value.replace(/\s+/g,' ').trim().split( ' ' );
fValue = parseFloat( fValue );
}
fUnits = fUnits || '';
if ( ValueUnits.unitsMap[ fUnits ] ) {
this.value = fValue;
this.units = fUnits;
} else {
this.value = fValue;
this.units = '';
}
}
toUnits( units ) {
if ( ValueUnits.unitsMap[ this.units ].dimension !== ValueUnits.unitsMap[ units ].dimension ) {
this.value = NaN;
this.units = null;
} else {
this.value = parseFloat( ( this.value * ValueUnits.unitsMap[ this.units ].conversion / ValueUnits.unitsMap[ units ].conversion ).toPrecision( 10 ) );
this.units = units;
}
return this;
}
unitsDimension() {
return ValueUnits.unitsMap[ this.units ].dimension;
}
}
ValueUnits.unitsMap = {
'': { dimension: 'number',conversion: 1},'%': { dimension: 'number',conversion: 1 / 100},'pts': { dimension: 'length',conversion: 1 },'px': { dimension: 'length',conversion: 72 / 128 },'in': { dimension: 'length',conversion: 72 },'"': { dimension: 'length','ft': { dimension: 'length',conversion: 72 * 12 },"'": { dimension: 'length','cm': { dimension: 'length',conversion: 72 / 2.54 },'mm': { dimension: 'length',conversion: 72 / 25.4 },'/pts':{ dimension: '/length',conversion: 1 / 1 },'/in': { dimension: '/length',conversion: 1 / 72 },'/px': { dimension: '/length',conversion: 128 / 72 },'l': { dimension: 'volume',// liters is base
'dl': { dimension: 'volume',conversion: 1 / 10 },'cl': { dimension: 'volume',conversion: 1 / 100 },'ml': { dimension: 'volume',conversion: 1 / 1000 },'oz': { dimension: 'volume',conversion: 1 / 33.814022702 },// us fluid ounce
'gal': { dimension: 'volume',conversion: 1 / 0.2641720524 },// us gallon
'qt': { dimension: 'volume',conversion: 1 / 1.0566882094 },// us quart
'pt': { dimension: 'volume',conversion: 1 / 2.1133764189 } // us pint
};
let x = new ValueUnits( '1 gal' );
console.log( x );
x.toUnits( 'oz' );
console.log( x );
x.toUnits( 'ml' );
console.log( x );
x.toUnits( 'l' );
console.log( x );
x.toUnits( 'qt' );
console.log( x );
x.toUnits( 'gal' );
console.log( x );
我意识到该类可能不完全适合您当前的代码构造方式,但是它抽象了不考虑单位的数量处理,并简化了向所需单位的转换。
请注意,“份”不是单位,而是物质之间的相对度量。也就是说,不能肯定地说part
是一个gal
,但是可以肯定地说1 qt
是0.25 gal
...
同样,体积等效项来自https://www.unitconverters.net/volume/liters-to-gallons.htm。