首页 > 解决方案 > 将数字转换为可读分数的角管

问题描述

我想创建一个 Angular 5 管道,它可以从数字中转换更易读的分数。

例如:

0,66 -> ⅔
0,25 -> ¼
1.25 -> 1 ¼

这是我已经拥有的,但我想让它更具活力:

export class FracturePipe implements PipeTransform {
  transform(value: any, args?: any): any {
    let roundedValue = Math.round(Number(value) * 100) / 100

    if (roundedValue === 0.66) {
      return '⅔'
    }
    //..and so on, but maybe there is a better way
  }
}

任何想法如何以更动态的方式做到这一点?

标签: angularangular-pipe

解决方案


尽管您可以使用外部库执行此操作,但使用 typescript 可以做到这一点,但使用欧几里得算法,您可以计算两个数字之间的最大公约数并除以您的十进制值,其中该十进制值计算为

const wholeNumber = Math.floor(input);
const decimal = input - wholeNumber;

这个管道的返回是一个字符串,首先是数字的整数值,然后是计算的分数(小数除以 gcd 和分数的底部除以 gcd )

示例:1.3 将返回1 3/10 然后您可以根据自己的喜好编辑管道的输出

 export class FracturePipe implements PipeTransform {
 transform(value: any, args?: any): any {

  if (value === parseInt(value)) {
        return value.toString();
      } else {
        let top = value.toString().includes('.') ? value.toString().replace(/\d+[.]/, '') : 0;
        const wholeNumber = Math.floor(value);
        const decimal = value - wholeNumber;
        const bottom = Math.pow(10, top.toString().replace('-', '').length);
        if (decimal >= 1) {
          top = +top + (Math.floor(decimal) * bottom);
        } else if (decimal <= -1) {
          top = +top + (Math.ceil(decimal) * bottom);
        }

        const x = Math.abs(this.gcd(top, bottom));
        if (wholeNumber === 0) {
          return (top / x) + '/' + (bottom / x);
        }
        return wholeNumber + ' ' + (top / x) + '/' + (bottom / x);
      }
}

gcd(a: number, b: number) {
    return (b) ? this.gcd(b, a % b) : a;
  }
}

推荐阅读