在Javascript中将十进制数转换为文本字符串分数?

5

我得到了一个返回数字的值,可能是小数,例如"1.15"。

然而,我需要将所有在特定范围内的数字格式化为给定的分数。例如,所有大于0但小于0.2的数字要返回"1/8"。

我已经开始使用一系列if/else语句来实现这个功能,但我想知道是否有更聪明、更整洁的方法。

if (amt > 0 && amt <= .2){
    q = '1/8';
} else if (amt > .2 && amt <= .3){
    q = '1/4';
}  else if (amt > .3 && amt <= .4){
    q = '1/3';
}  else if (amt > .4 && amt <= .5){
    q = '1/2';
} else if (amt > .5 && amt <= .7){
    q = '2/3';
} else if (amt > .7 && amt <= .8){
    q = '3/4';
} else if (amt > .8 && amt <= 1.0){
    q = '7/8';
} else if (amt > 1 && amt <= 1.1){
    q = '1';
} etc.....

为什么要使用这么多的 else if 语句呢?为什么不用 switch case 呢? - Joseph Silber
switch case 只接受一个值,意味着相等 (=)。 - Diodeus - James MacFarlane
@joseph 如果值是像 .22 .23 .25 .27 这样的,你会如何使用 switch case? - zod
不清楚的是,当您达到大于1的值时会发生什么?例如对于1.5,您是否会返回“1 1/2”这样的结果? - user229044
@Diodeus:没错,但你可以通过一些技巧让它为你评估一些东西:http://jsfiddle.net/9XWAA/,虽然`switch`的主要思想是*简化*问题,而不是使它们复杂化 ;) - Joseph Silber
4个回答

3

将您的代码移入一个函数中,并且您可以从正确的分支return,跳过所有的else语句,这样可以极大地简化代码:

function toFraction(amt) {
  if (amt > 0 && amt <= .2) return '1/8';
  if (amt <= .3) return '1/4';
  if (amt <= .4) return '1/3';
  if (amt <= .5) return '1/2';
  // etc
}

如果输入小于零,此代码将返回“1/4”;需要从if (amt <=0) {//do something}开始。话虽如此,这绝对是我会使用的结构类型,尽管我认为这里最大的改进不是将其放在自己的函数中,而是在每个测试中删除无意义的最小值测试(当然,只要您按正确顺序进行测试,就不需要这些测试)。 - nnnnnn
@nnnn 这段代码仅执行原始示例代码所做的操作。在传递给函数的amt值方面,存在某些假设。 - user229044
但它们并不是做同样的事: 原始示例对于0或更小的值具有未定义的结果,因为这不匹配我们看到的任何if条件,而你的代码在第二个条件中匹配了'1/4'这个结果...我只是想确保原帖作者没有忘记处理0和负数。 - nnnnnn

3

Ratio.js有一个名为.toQuantityOf()的函数。

.toQuantityOf()在提供的单位基础上,将分数的当前值转换为其近似值,并返回一个新的分数。如果作为参数传递了多个单位,则会返回最接近原始值的匹配项。

.toString()将分数作为字符串返回。

var fraction = Ratio.parse("1.15").toQuantityOf(2,3,4,8);
fraction.toString() == "9/8";

.toLocaleString()方法会根据需要返回混合数字。

fraction.toLocaleString() == "1 1/8";

1

您可以对amt执行数学运算,将其转换为范围内的整数值,然后将其用作数组查找的索引以获取分数文本。

如果您的范围相等,那么这可能很简单,但由于您有一些1/10(0.3到0.4)和一些2/10(0.5到0.7),所以它会更加复杂,不仅仅是乘以10。


fractional = {
    fractions: [ "1/8", "1/8", "1/4", "1/3", "1/2", "2/3", "2/3", "3/4", "7/8", "1" ],
    toFraction: function(amt) {
        return this.fractions[(""+(amt*10)).split('.')[0]];
    }
};

alert(fractional.toFraction(0.37));

这是一个很好的想法,但是由于 alert(fractional.toFraction(.5)); 给出了 2/3(数组中的第六项),所以它不能正确地工作。此外,当有大于1的数字时(例如1.35),它也会出现错误。 - Steve
@Steve - 是的,简单地乘以10几乎从来不是正确的做法,就像我在我的答案中最初提到的那样。我通常需要做一些像加上半个单位、乘以、四舍五入以获得正确的数字。否则,我不确定我是否将分数的正确文本放在了数组的正确位置,但这很容易调整,最后,这种技术必然限制了你的范围,但接受的答案也是如此。任何一种情况都必须通过将分数部分与整数部分分开处理来处理n>1 - Stephen P

0
  1. amt乘以10并获取整数部分
  2. 从之前构建的数组中查找相应的字符串!

NB-该数组是固定的,因此是静态的


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接