javascript - 有没有更好的写作方式v=(v==0?1:0);




variables coding-style toggle code-golf (25)

我想在0和1之间切换一个变量。如果它是0,我想将它设置为1,否则如果它是1,我想将它设置为0。

这是一个非常基本的操作,我经常写这个操作,我想调查一下最简单,最清晰的方法。 这是我迄今为止最好的:

v = (v == 0 ? 1 : 0);

你能改进吗?

编辑:问题是如何在保持清晰度的同时以最少的字符编写上述语句 - 这是不是一个真正的问题? 这并不是要进行代码高尔夫练习,尽管一些有趣的答案已经从人们接近高尔夫的角度出现 - 很高兴看到高尔夫被用于建设性和发人深省的方式。


Answers

Well, As we know that in javascript only that Boolean comparison will also give you expected result.

ie v = v == 0 is enough for that.

Below is the code for that:

var v = 0; 
alert("if v  is 0 output: "+ (v == 0) );

setTimeout(function(){
v = 1; 
alert("if v  is 1 Output: "+ (v == 0) );
}, 1000);

JSFiddle: https://jsfiddle.net/vikash2402/83zf2zz0/

Hoping this will help you :)


v=!v;

will work for v=0 and v=1; and toggle the state;


v = !v * 1

multiplying by 1 to turn boolean into number


我会让它更加明确。

v是什么意思?

例如,当v是某种状态时。 创建一个对象状态。 在DDD中是一个值对象。

在这个值对象中实现逻辑。 然后你可以用更可读性更好的方式编写你的代码。 根据当前状态创建新状态可以完成切换状态。 然后,你的if语句/逻辑被封装在你的对象中,你可以单元测试。 valueObject总是不变的,所以它没有身份。 所以要改变它的价值,你必须创造一个新的。

例:

public class Status
{
    private readonly int _actualValue;
    public Status(int value)
    {
        _actualValue = value;
    }
    public Status(Status status)
    {
        _actualValue = status._actualValue == 0 ? 1 : 0; 
    }

    //some equals method to compare two Status objects
}

var status = new Status(0);

Status = new Status(status);

你可以为它编写一个函数并像下面这样使用它:

v = inv(v)


由于这是JavaScript,我们可以使用一元+来转换为int:

v = +!v;

这将逻辑NOT v的值(如果v == 0 ,则返回false如果v == 1 false )。 然后我们将返回的布尔值转换为其对应的整数表示形式。


v = v == 0 ? 1 : 0;

足够 !


解决方案列表

我想提出三种解决方案。 他们都将任何值转换为0 (如果1true等)或1 (如果0falsenull等):

  • v = 1*!v
  • v = +!v
  • v = ~~!v

和另外一个,已经提到,但聪明和快速(虽然只适用于0秒和1秒):

  • v = 1-v

解决方案1

您可以使用以下解决方案:

v = 1*!v

这将首先将整数转换为相反的布尔值( 0True ,其他值为False ),然后在乘以1时将其视为整数。 结果0将被转换为1而其他值将被转换为0

作为证明,请参阅此jsfiddle并提供您希望测试的任何值: jsfiddle.net/rH3g5/

结果如下:

  • -123将转换为整数0
  • -10将转换为整数0
  • -1将转换为整数0
  • 0将转换为整数1
  • 1将转换为整数0
  • 2将转换为整数0
  • 60将转换为整数0

解决方案2

正如mblase75指出的那样,jAndy还有一些其他解决方案可以像我一样工作:

v = +!v

它也首先使原始值为布尔值,但使用+而不是1*将其转换为整数。 结果完全一样,但符号较短。

解决方案3

另一种方法是使用~~运算符:

v = ~~!v

这是非常罕见的,总是从布尔转换为整数。


你可以简单地使用:

v = 1 - v;

这当然假定变量被正确初始化,即它只有值0或1。

另一种较短但使用不太常见的运算符的方法:

v ^= 1;

编辑:

清楚; 我从来没有把这个问题看作代码高尔夫,只是为了找到一个简短的方式来完成这个任务,而不使用任何模糊的技巧,比如运营商的副作用。


一般情况下,无论何时需要在两个值之间切换时,都可以从两个切换值的总和中减去当前值:

    0,1 -> v = 1 - v
    1,2 -> v = 3 - v
    4,5 -> v = 9 - v 

如果你不关心除1之外的任何可能性:

v = v ? 0 : 1;

在上述情况下,如果v为0,false,undefined或null,则v最终将为1。 小心使用这种方法 - 即使v是“hello world”,v也是0。


原始解决方案的另一种形式:

v = Number(v == 0);

编辑:感谢TehShrike和Guffa指出我的原始解决方案中的错误。


由于0false值, 1true值。

v = (v ? 0 : 1);

如果你很乐意使用truefalse来代替数字

v = !v;

或者如果他们必须是数字:

v = +!v; /* Boolean invert v then cast back to a Number */

If there are just two values, as in this case(0, 1), i believe it's wasteful to use int. Rather go for boolean and work in bits. I know I'm assuming but in case of toggle between two states boolean seems to be ideal choice.


Another creative way of doing it, with v being equal to any value, will always return 0 or 1

v = !!v^1;

总结另一个答案,评论和我自己的意见,我建议结合两件事情:

  1. 使用切换功能
  2. 在这个函数里面使用一个更可读的实现

这里是你可以放在一个库中的函数,也可以把它包装在另一个Javascript框架的插件中。

function inv(i) {
  if (i == 0) {
    return 1
  } else {
    return 0;
  }
}

用法很简单:

v = inv(v);

优点是:

  1. 没有代码复制
  2. 如果您或将来再次阅读此内容,您将在最短的时间内了解您的代码。

诚实和数学的完整性 - 考虑到这个“答案”的票数 - 让我编辑这个答案,我尽可能拖延,因为它只是一个简短的琐碎,而不是“深”的东西,所以把任何解释似乎都与目的背道而驰,但评论清楚地表明我应该清楚避免误解。

我原来的答案是:

这部分规范的措辞:

如果它是0,我想将它设置为1,否则将其设置为0。

意味着最准确的解决方案是:

v = dirac_delta(0,v)

首先,忏悔:我确实让我的三角函数感到困惑。 克罗内克三角洲可能稍微适合,但不是太多,因为我想要的是独立于域的东西(克罗内克三角洲主要用于整数)。 但我真的不应该使用delta函数,我应该说:

v = characteristic_function({0},v)

让我澄清一下。 回想一下,一个函数是一个三元组, (X,Y,f) ,其中XY是集合(分别称为codomain ), f是一个将Y的元素分配给X的每个元素的规则。 我们经常将三元(X,Y,f)写成f:X→ Y。 给定X的一个子集,比如A ,有一个特征函数是一个函数x A :X→ {0,1} (它也可以被认为是一个更大的共域的函数,如ℕ或ℝ)。 该功能由规则定义:

如果x∈ x A (x)= 1 ; AχA(x)= 0,如果x∉A

如果你喜欢真值表,它是问题“ X的元素x是子集A的一个元素吗?”的真值表。

所以根据这个定义,很明显特征函数就是这里所需要的, X是包含0和A = {0}的大集合。 这就是我应该写的。

对三角函数也是如此。 为此,我们需要了解整合。 要么你已经知道它,要么你不知道。 如果你不这样做,我在这里可以说的任何东西都不会告诉你这个理论的复杂性,但我可以给出一个句子的总结。 对于集合X的 度量本质上是“为了平均工作所需要的”。 也就是说,如果我们有一个集合X和一个度量μ ,那么就有一类函数X→ ℝ ,称为可测函数 ,其表达式∫X fdμ有意义,并且在某种模糊的意义上,是X上f的“平均值”。

给定集合上的度量,可以为该集合的子集定义“度量”。 这是通过给子集分配其特征函数的积分来完成的(假设这是一个可测量的函数)。 这可以是无限的, 也可以是未定义的(两者略有不同)。

周围有很多措施,但这里有两个重要的措施。 一个是真正的标准措施 ,&Ropf ;. 对于这个测量,然后ℝ fdμ几乎是你在学校教过的东西(微积分仍然是在学校教授的):总结一些小矩形,并采用越来越小的宽度。 在这种测量中,间隔的量度是其宽度。 一个点的度量是0。

另一个重要的措施,适用于任何集合,称为点测量 。 它被定义为使得函数的积分是其值的总和

∫X fdμ=Σx ∈ X f(x)

这个度量为每个单身人群设定了度量1.这意味着子群的有限度量当且仅当它本身是有限的。 很少有函数具有有限积分。 如果一个函数有一个有限积分,它只能在数的点上非零。 所以你可能知道的绝大多数函数在这个度量下没有有限的积分。

现在转向三角函数。 我们来定义一个非常宽泛的定义。 我们有一个可测量的空间(X,μ) (所以这是一个有度量的集合)和一个元素a∈ X。 我们将delta函数 (取决于a )定义为“函数” δa:X→ ℝ 如果x≠a∫Xδadμ= 1,则具有 δa (x)= 0 性质

关于这一点最重要的事实是:delta函数不必是一个函数 。 它没有正确定义:我没有说过δa(a)是什么。

你在这一点上所做的取决于你是谁。 这里的世界分为两类。 如果你是数学家,你可以这样说:

好的,delta函数可能没有定义。 让我们来看看它的假设属性,看看我们是否能够在它定义的地方找到合适的家。 我们可以做到这一点,我们最终得到分配 。 这些不是 (必然)功能,而是与功能有点类似的东西,我们经常可以像功能一样与它们一起工作; 但有一些他们没有的东西(比如“价值”),所以我们需要小心。

如果你不是数学家,你可以这样说:

好的,delta函数可能没有正确定义。 谁这么说? 一群数学家? 别理他们! 他们知道什么?

现在冒犯了我的听众,我会继续。

狄拉克三角洲通常被认为是一个点(通常为0)在实际情况下与其标准测量值的δ函数。 所以那些在评论中抱怨我不知道我的增量的人是这样做的,因为他们正在使用这个定义。 对他们来说,我很抱歉:尽管我可以通过使用数学家的辩护 (正如Humpty Dumpty所推崇的那样:简单地重新定义一切以便它是正确的)来避免这种情况,但使用标准术语来表示不同的东西是不好的形式。

但是有一个delta函数可以做我想做的事情,而这正是我需要的。 如果我对一个集合X做一个点测度 ,那么就有一个真正的函数δa:X→ ℝ 它满足delta函数的标准。 这是因为我们正在寻找一个函数X→ ℝ 除了在a和它的所有值的总和为1之外,它是零。这样的函数很简单:唯一缺失的信息是其在a值,并且为了得到总和为1,我们只将它分配给值为1.这不过是{a}上的特征函数。 然后:

∫Xδadμ=Σx ∈ Xδa(x)=δa(a)= 1。

因此,在这种情况下,对于单例集,特征函数和delta函数是一致的。

总之,这里有三个“功能”家族:

  1. 单身人士套装的特色功能,
  2. 三角函数,
  3. 克罗内克三角函数。

其中第二个是最一般的,因为其他任何一个都是使用点测量时的一个例子。 但是第一和第三的优点是它们总是真正的功能。 第三个实际上是第一个特殊情况,对于特定的域系列(整数或其子集)。

所以,最后,当我最初编写答案时,我并没有正确思考(我不想说我很困惑 ,因为我希望我已经证明了我知道我在说什么时候我其实首先想到,我只是没有多想)。 狄拉克三角洲的通常含义并不是这里所要求的,但我的答案的要点之一是输入域没有被定义,所以克罗内克三角洲也不会是正确的。 因此,最好的数学答案(我所瞄准的)将是特征函数。

我希望这一切都清楚; 而且我也希望我再也不用使用HTML实体而不是TeX宏来编写数学片段了!


仅用于踢腿: v = Math.pow(v-1,v)也可以在1和0之间切换。


我不知道你为什么要建立你自己的布尔值? 我喜欢时髦的语法,但为什么不写可理解的代码?

这不是最短/最快的,但最清晰(每个人都可读)使用众所周知的if / else状态:

if (v === 0)
{
  v = 1;
}
else
{
  v = 0;
}

如果你想清楚一点,你应该使用布尔值代替数字。 它们对大多数情况下足够快。 有了布尔类型,你可以使用这个语法,这将赢得简短:

v = !v;

v = 1 - v ,或v ^= 1v= +!v行将完成所有工作,但它们构成了我所称的黑客行为。 这些并不是美丽的代码,而是具有预期效果的廉价技巧。 1 - v不通信“在0和1之间切换值”。 这会让你的代码表现力减弱,并引入一个地方(尽管很小),另一个开发人员将不得不分析你的代码。

取而代之的是像v = toggle(v)这样的函数以最快的速度传达意图。



如果它必须是整数1或0,那么你做的方式很好,尽管不需要括号。 如果这些a被用作布尔值,那么你可以这样做:

v = !v;

如果你保证你的输入是1或0,那么你可以使用:

v = 2+~v;

If possible values for v are only 0 and 1, then for any integer x, the expression: v = Math.pow((Math.pow(x, v) - x), v); will toggle the value.

I know this is an ugly solution and the OP was not looking for this...but I was thinking about just another solution when I was in the loo :P


我会建议使用下面的字符串组合来检查是否使用了设备类型。

根据Mozilla文档字符串Mobi推荐。 但是,如果仅使用Mobi ,某些旧平板电脑不会返回true,因此我们也应该使用Tablet字符串。

同样,为了安全起见,还可以使用iPadiPhone字符串来检查设备类型。

大多数新设备将单独为Mobi字符串返回true

if (/Mobi|Tablet|iPad|iPhone/.test(navigator.userAgent)) {
    // do something
}






javascript variables coding-style toggle code-golf