Javascript 有点痛苦的三重嵌套三值运算符

Javascript 有点痛苦的三重嵌套三值运算符,javascript,if-statement,ternary-operator,Javascript,If Statement,Ternary Operator,我浏览了Raphael.js的源代码,了解他是如何将RGB值转换为HSB的。我发现了他使用的函数,当时我正在将其转换为Python,这时我遇到了这个漂亮的三重嵌套三值运算符: H = (C == 0 ? null : V == r ? (g - b) / C : V == g ? (b - r) / C + 2 : (r - g) / C + 4 ); 这让我陷入了一个循环,因为Python没有Javascript那样的三元运算符。我花了一段时

我浏览了Raphael.js的源代码,了解他是如何将RGB值转换为HSB的。我发现了他使用的函数,当时我正在将其转换为Python,这时我遇到了这个漂亮的三重嵌套三值运算符:

H = (C == 0 ? null :
    V == r ? (g - b) / C :
    V == g ? (b - r) / C + 2 :
             (r - g) / C + 4
    );
这让我陷入了一个循环,因为Python没有Javascript那样的三元运算符。我花了一段时间查看它,最终从中散列出了这段稍微理智一些的代码(仅使用if/else):

if (C == 0) {
    H = null;
} else {
    if(V == r) {
        H = (g - b) / C;
    } else {
        if(V == g) {
            H = (b - r) / C + 2;
        } else {
            H = (r - g) / C + 4;
        }
    }
}

我的解释正确吗?我之所以问这个问题,是因为如果它不正确,我将面临大量调试。所以我“明白”了吗?

我想你可以用这个来避免深嵌套:

var H

if(C == 0){
    H = null;
}
else if(V == r){
    H = (g - b) / C;
}
else if (V == g){
    H = (b - r) / C + 2;
}
else {
    H = (r - g) / C + 4;
}

同样的逻辑可以用更简单的方式编写:

var H

if (C == 0)
    H = null;
else if (V == r)
    H = (g - b) / C;
else if (V == g)
    H = (b - r) / C + 2;
else
    H = (r - g) / C + 4;
可以省略大括号,因为每个条件中只有一条语句。考虑到这些条件是相互排斥的,使用
else if
比嵌套
if
更清晰。

是的,这是正确的(除了资本化差异)。然而,它可能写得更干净,没有任何括号,可读性与elseif一样:

if (C == 0)
    h = null;
else if (V == r)
    h = (g - b) / C;
else if (V == g)
    h = (b - r) / C + 2;
else
    h = (r - g) / C + 4;

根据我个人的口味,一个仔细排列的嵌套三元组胜过if-else混乱:

const H =
  C == 0 ? null            :
  V == r ? (g - b) / C     :
  V == g ? (b - r) / C + 2 :
           (r - g) / C + 4 ;
我见过丹·阿布拉莫夫使用这种压痕放置模式。虽然我不喜欢条件运算符
如何不再直观地遵循条件,但我更喜欢这一点,而不是像@lolmaus的示例,因为无论条件运算符的大小,缩进总是一致的


实际上,您开始将其视为
true
false,这在这里是直观的。这样,我发现三元更容易发现和区分周围的代码。

< P>如果你的JavaScript代码库包含嵌套的三元语句,比如一个问题,考虑将格式化转换为。 他们只是在一条直线上从上到下读取,返回一个值 一旦他们遇到真实情况或撤退

你好,埃里克·埃利奥特


还有一个更优雅的想法

if (C != 0) 
{
  if (V == r) return (g - b) / C;
  if (V == g) return (b - r) / C + 2;
  return (r - g) / C + 4;
}

return null;
只需将其包装在函数中并使用,而不是如中所述的H..


为什么不使用Python中的三元运算符

H=(
如果C==0,则为无
如果V==r,则为(g-b)/C
(b-r)/C+2如果V==g
(r-g)/C+4
)


是的,看起来你的逻辑是正确的,除了几个大写的不一致性,第一个
c
at
if(c==0)
应该是大写的
c
,不是吗?嗯,是吗?我感觉自己就像一个被绑在背后,蒙着眼睛,对着飞镖板投飞镖的人,还射中了一个靶子。是的,@NiftyDude,没错。谢谢你的接球!看起来不错。既然您正在转换为python,我相信您不会在意这种情况,但请注意JavaScript中的
==
确实存在类型强制,因此两者可能会有所不同。@dwerner:是的,确实如此。谢谢你指出这一点。很酷,谢谢。不过,我主要是在寻找逻辑验证,仅供参考。:)人们普遍认为,不使用括号所节省的空间/清洁度大大超过了对代码可维护性的危险影响。因为我将把它转换成Python,所以语法并不重要。不过还是要谢谢你!我认为python的等价物应该是
elif
。。。每个人似乎都想指出的一点是避免不必要的缩进。@GGG:没错。是的。我想如果你是一个程序员,你的本能就是让任何东西都可读。。。这不能怪任何人!人们普遍认为,不使用括号所节省的空间/清洁度大大超过了对代码可维护性的危险影响@道格:几乎不会有第二次声明;此代码的唯一目的是为单个变量赋值。此外,OP正在将其转换为Python,在Python中实际上不强制使用括号:-)为什么不使用nice呢@GustvandeWal你知道这是5年前回答的,对吗?然而在webkit中嵌套一元表达式比if或switch慢60%,而在geco中则慢一点。@Zydnar,我不知道,伙计。我刚刚在Chrome控制台中运行了一个简单的基准测试,如果其他测试速度较慢:。无论使用何种变体,单个操作大约需要
0.00000000 1
秒。这是一纳秒,所以你在为皮秒的差异而斗争!如果您正在按程序实时生成数据,那么这可能很重要。然而,对于绝大多数JS开发人员来说,这种差异是完全可以忽略不计的。不过,最重要的是代码可读性和开发速度。请注意,一次迭代的纳秒数包括花费在
for
逻辑和
=
分配上的时间。这取决于项目,如果它是一个简单的网站,你不在乎它是否是一个具有大数据的高性能项目。。。除此之外,eslint也会将嵌套的十进制标记为坏习惯,除非您将其关闭。简单的基准测试并不重要,因为有很多原因,甚至一些后台程序或插件也会影响它。好的,我的坏if-else慢,但切换比一元数和if-else快
H = (C == 0)           // Is C zero?
    ? null             // Then return `null`, else ...
    : (V == r)         // Is V equal to r?
    ? (g - b) / C      // Then return this value, else ...
    : (V == g)         // Is V equal to g?
    ? (b - r) / C + 2  // Then return this value
    : (r - g) / C + 4; // Otherwise fall back to this default value
if (C != 0) 
{
  if (V == r) return (g - b) / C;
  if (V == g) return (b - r) / C + 2;
  return (r - g) / C + 4;
}

return null;
function example(…) {
    return condition1 ? value1
         : condition2 ? value2
         : condition3 ? value3
         : value4;
}

// Equivalent to:

function example(…) {
    if (condition1) { return value1; }
    else if (condition2) { return value2; }
    else if (condition3) { return value3; }
    else { return value4; }
}