Skip to content

Instantly share code, notes, and snippets.

@ronaldaug
Last active September 20, 2023 04:55
Show Gist options
  • Save ronaldaug/0d50d43083c2bff57aeeb73889ff04ba to your computer and use it in GitHub Desktop.
Save ronaldaug/0d50d43083c2bff57aeeb73889ff04ba to your computer and use it in GitHub Desktop.
Units Convertor For Any Units - Javascript

CUnit

CUnit - Convert any units.

The below example shows calculating cigaratte, pack, cartoon and box. You can add any units to data_array and calculate among units.

const data_array = [
  {
    unit: "cigaratte",
    rate: 20
  },
  {
    unit: "pack",  // 20 cigarattes = 1 pack
    rate: 12
  },
  {
    unit: "cartoon", // 10 packs = 1 cartoon
    rate: 10
  },
  {
    unit: "box", // 10 cartoon = 1 box
    rate: 1
  },
];

class CUnit {
  constructor(data_array, options) {
    this.data_array = data_array;
    this.in_decimal = options?.in_decimal;
    this.decimal_count = options?.decimal_count ?  options?.decimal_count : 2 
  }

  countDecimal(number){
    const numberString = number.toString();
    if (numberString.includes('.')) {
      return parseInt(Math.ceil(number));
    } else {
      return number;
    }
  }
  
 findIndexNumbersBetween() {
     let start = this.fromIndex;
     let end = this.toIndex;
      if(start > end){
          let prevEnd = end;
          end   = start;
          start = prevEnd;
      }
      const betweenIndexes = [];
      for (let i = start + 1; i < end; i++) {
        betweenIndexes.push(i);
      }
      return betweenIndexes;
  }

  multiplyOtherIndexes(otherIndexes){
         otherIndexes.push(this.toIndex) // add to Index; 
         let otherIndexesMin = otherIndexes.sort((a, b) => a - b);
         let indexRates = otherIndexesMin.map(e=>this.data_array[e].rate).reduce((a,b)=> a * b); 
         return this.amount * indexRates;
  }

  divideOtherIndexes(otherIndexes){
         otherIndexes.push(this.fromIndex) // add to Index; 
         let otherIndexesMin = otherIndexes.sort((a, b) => a - b);
         return otherIndexesMin.map((e,i)=>{
               // if fromIndex
               if(i === 0){
                 return this.amount / this.data_array[e].rate;
               }
               return this.data_array[e].rate;
          }).reduce((a,b)=>a/b) 
  }

  convert(amount, from, to) {
      
    this.amount = amount;
    this.fromIndex = this.data_array.findIndex(item => item.unit === from);
    this.toIndex = this.data_array.findIndex(item => item.unit === to);
  
    this.fromRate = this.data_array[this.fromIndex].rate;
    this.toRate   = this.data_array[this.toIndex].rate; 
    

    // higher to lower
    let convertedAmount = this.fromIndex > this.toIndex ? this.amount * this.toRate : this.amount / this.fromRate;  
    let otherIndexes = this.findIndexNumbersBetween();
    if(otherIndexes.length > 0){
           convertedAmount = this.fromIndex > this.toIndex ? this.multiplyOtherIndexes(otherIndexes) : this.divideOtherIndexes(otherIndexes);
    }
    return this.formatAmount(convertedAmount)     
  }

  formatAmount(convertedAmount){
     if(this.in_decimal){
        return Number(convertedAmount.toFixed(this.decimal_count));
     }
     return Number(this.countDecimal(convertedAmount));
  }
}

const cunit = new CUnit(data_array,{in_decimal:true,decimal_count:5});
console.log(cunit.convert(12, "pack", "box")) // 0.1

Usage

const cunit = new CUnit(data_array,{in_decimal:true,decimal_count:5});
console.log(cunit.convert(12, "pack", "box")) // 0.1
console.log(cunit.convert(1, "cigaratte", "cartoon")) // 0.00417
console.log(cunit.convert(12, "cartoon", "pack")) // 144
console.log(cunit.convert(1, "pack", "cigaratte")) // 20 
console.log(cunit.convert(2, "box", "cigaratte")) // 4800

Options

option type default available values description
in_decimal boolean false true/false we can use in_decimal when we what the output with decimals e.g instead of 1, it'll output 1.05
decimal_count number 2 0 to 10 It's the same with js's toFixed . E.g if we set 4 , it'll show 4 decimals 0.0245
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment