烹饪单位计量转换库

问题描述

我正在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 qt0.25 gal ...

同样,体积等效项来自https://www.unitconverters.net/volume/liters-to-gallons.htm