是否有更好的书写方式v =(v == 0?1:0); [关闭]

2020/09/26 04:47 · javascript ·  · 0评论

我想在0到1之间切换变量。如果是0,我想将其设置为1,否则,如果是1,我想将其设置为0。

这是一个非常基本的操作,我经常写,我想研究最短,最清晰的方法。到目前为止,这是我最好的:

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

您可以对此进行改进吗?

编辑:问题是询问如何用最少的字符写以上语句,同时保持清晰度-这个“不是真正的问题”吗?这样做并不是要进行代码高尔夫练习,尽管人们从高尔夫运动中获得了一些有趣的答案-很高兴看到高尔夫以建设性和发人深省的方式使用。

您可以简单地使用:

v = 1 - v;

当然,这假设变量已正确初始化,即变量值仅为0或1。

另一种较短但使用较少通用运算符的方法:

v ^= 1;

编辑:

要清楚;我从来没有以代码高尔夫的方式来回答这个问题,只是找到了一种完成任务的简短方法而没有使用任何晦涩的技巧,例如操作员的副作用。

因为0是一个false价值,1是一个true价值。

v = (v ? 0 : 1);

如果您乐于使用truefalse不是数字

v = !v;

或如果它们必须是数字:

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

v = (v + 1) % 2如果你通过更多的值需要周期只是改变2(n + 1)假设您需要循环0,1,2就可以了v = (v + 1) % 3

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

v = inv(v)

如果您不关心除1以外的任何可能性:

v = v ? 0 : 1;

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

v = 1 - v,或v ^= 1v= +!v这样的行都可以完成工作,但是它们构成了我所说的hack。这些不是漂亮的代码行,而是可以达到预期效果的廉价技巧。1 - v不传达“在0和1之间切换值”。这使您的代码表达能力降低,并引入了一个地方(尽管很小),另一个开发人员将不得不解析您的代码。

取而代之的是具有类似功能的v = toggle(v)信息可以一目了然地传达意图。

出于对这个“答案”的投票数,诚实和数学上的正直使我编辑了这个答案。我之所以推迟了尽可能长的时间,是因为这只是一个简短的讽刺,而不是任何“深入”的内容,因此请输入任何解释似乎都与目的相反。但是,评论清楚表明我应该清楚避免误解。

我的原始答案:

规范这部分的措辞:

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

表示最准确的解决方案是:

v = dirac_delta(0,v)

首先,告白:我确实使我的delta函数感到困惑。Kronecker增量本来应该更合适一些,但并不是我想要的与域无关的东西(Kronecker增量主要用于整数)就没有那么多。但是我真的不应该使用增量函数,我应该说:

v = characteristic_function({0},v)

让我澄清一下。回想一下,函数是一个三元组(X,Y,f),其中XY是集合(分别称为和共),而f是将Y的元素分配给X的每个元素的规则我们通常将三元组(X,Y,f)写f:X→Y给定的一个子集X,说,有一个特征函数是一个函数χ :X→{0,1}(也可以将其视为较大的共域(例如ℕ或ℝ)的函数)。该功能由以下规则定义:

χ (X)= 1如果X∈Aχ (X)= 0,如果X∉甲

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

因此,从这个定义可以明显看出,这里需要特征函数,其中X包含0和A = {0}的某个大集合那是我应该写的。

以此类推。为此,我们需要了解集成。您要么已经知道,要么不知道。如果您不这样做,那么我在这里无话可说,无法告诉您该理论的复杂性,但是我只能给出一句话的摘要。本质上,对集合X的度量是“使平均值起作用所需度量 ”。这就是说,如果我们有一组X和措施μ上设置,那么有一类的功能X→ℝ,呼吁测函数该表达式X ˚Fdμ是有道理的,并且,在一些模糊的感觉,fX上的“平均值”

给定一个度量集,就可以为该集合的子集定义一个“度量”。这是通过向子集分配其特征函数的积分来完成的(假定这是可测量的函数)。可以是无限的,也可以是不确定的(两者有细微的差别)。

周围有很多措施,但是这里有两项很重要。一种是实线上标准度量,。对于这一措施,那么 ˚Fdμ是相当多你得到在学校任教(微积分是在学校还是教授):总结小矩形,并采取小的宽度。在此度量中,间隔的度量是其宽度。点的度量为0。

适用于任何集合的另一个重要度量称为点度量定义函数的积分是其值总和

X ˚Fdμ=Σ X∈X F(X)

该度量将度量1分配给每个单例集。这意味着,当且仅当子集本身是有限的时,子集才具有有限度量。很少有函数具有有限积分。如果函数具有有限积分,则仅在数的点上它必须为非零因此,您可能知道的绝大多数功能在这种情况下都不具有有限积分。

现在到增量功能。让我们进行非常广泛的定义。我们有一个可测量的空间(X,μ)(所以这是一个带有度量的集合)和一个元素a∈X我们以“限定的” δ函数(取决于)为“功能” δ 一个:X→ℝ与属性,δ 一个(X)= 0,如果X≠一个X δ 一个 dμ= 1

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

此时您要做什么取决于您是谁。这里的世界分为两类。如果您是数学家,请说以下内容:

好的,因此可能未定义delta函数。让我们来看看它的假设性,看看我们是否能够找到合适的住所为它在那里它定义。我们可以做到这一点,最后得到分布这些不是(不一定)函数,而是行为有点像函数的事物,通常我们可以像对待函数一样使用它们。但是有些东西是它们所没有的(例如“值”),因此我们需要小心。

如果您不是数学家,请说以下内容:

好的,因此可能未正确定义增量功能。谁这么说 一堆数学家?别管他们!他们知道什么?

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

狄拉克δ通常取为与它的标准度量实线上的点(通常0)的δ函数。因此,那些在评论中抱怨我的人不知道我的增量是否在这样做,因为他们正在使用此定义。对于他们,我深表歉意:尽管我可以通过使用数学家的防御方法来避免这种情况(由Humpty Dumpty推广:只需重新定义所有内容,使其正确无误),但是使用标准术语来表示不同的含义是一种不好的形式。

但是,它确实做我想做的事情,它是我在这里需要一个δ函数。如果我采取点措施上的一组X一个真正的函数δ 一个:X→ℝ其满足用于delta函数的标准。这是因为我们正在寻找一个函数X→ℝ是零,除了在一个,并且使得其所有值的总和为1,这样的功能是简单的:的信息的唯一缺少的部分是其在值一个,和要使总和为1,我们只需为其分配值1。这就是{a}上的特征函数然后:

X δ 一个 dμ=Σ 的x∈X δ 一个(X)=δ 一个(A)= 1。

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

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

  1. 单例集的特征函数,
  2. 增量功能
  3. Kronecker增量功能。

其中第二个是最通用的,因为其他任何一个都是使用点测度时的一个示例。但是第一个和第三个具有的优点是它们始终是真正的功能。第三个实际上是第一个的特殊情况,对于特定的域家族(整数或它们的某个子集)。

所以,最后,当我最初写答案时,我并没有正确地思考(我不会走到说我很困惑的程度,因为我希望我已经证明我确实知道我在说什么。实际上我首先想到的是,我只是想的不多。狄拉克三角洲的通常含义是不是在这里想要的,但我的答案的要点之一是,输入域是没有定义,因此Kronecker符号也将不会是正确的。因此,最好的数学答案(我的目标是)是特征函数。

我希望一切都清楚。而且我也希望我不必再使用HTML实体而不是TeX宏来编写数学文章!

你可以做

v = Math.abs(--v);

减量Math.abs会将值设置为0或-1,然后将-1转换为+1。

通常,只要需要在两个值之间切换,就可以从两个切换值的总和中减去当前值:

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

如果它必须是整数1或0,则尽管不需要括号,但您的操作方式也很好。如果将这些a用作布尔值,则可以执行以下操作:

v = !v;
v = v == 0 ? 1 : 0;

足够的 !

解决方案清单

我想提出三种解决方案。所有这些转换为任意值0(如1true等)或1(如果0falsenull等):

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

还有一个已经提到过的方法,但是又聪明又快速(尽管仅适用于0s和1s):

  • v = 1-v

解决方案1

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

v = 1*!v

这将首先将整数转换为相反的布尔值(0to True和其他任何值to 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

它很少见,总是从布尔值转换为整数。

为了总结另一个答案,评论和我自己的观点,我建议结合以下两点:

  1. 使用功能进行切换
  2. 在此函数内使用更易读的实现

这是您可以放置​​在库中或者可以将其包装在另一个Javascript框架的插件中的函数。

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

用法很简单:

v = inv(v);

优点是:

  1. 没有代码重复
  2. 如果将来您或任何人再次阅读此书,您将在最短的时间内理解您的代码。

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

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

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

如果您想弄清楚,应该为此使用布尔值而不是数字。在大多数情况下,它们足够快。使用布尔值时,您可以只使用以下语法,这将在短时间内获胜:

v = !v;

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

v = Number(v == 0);

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

我会更加明确。

什么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 = ~(v|-v) >>> 31;

这是缺少的:

v = [1, 0][v];

它也可以用作循环轮询:

v = [2, 0, 1][v]; // 0 2 1 0 ...
v = [1, 2, 0][v]; // 0 1 2 0 ...
v = [1, 2, 3, 4, 5, 0][v]; // 0 1 2 3 4 5 ...
v = [5, 0, 1, 2, 3, 4][v]; // 0 5 4 3 2 1 0 ...

要么

v = {0: 1, 1: 0}[v];

最后一个解决方案的魅力在于,它也适用于所有其他值。

v = {777: 'seven', 'seven': 777}[v];

对于非常特殊的情况,例如要获得一个(变化的)值和undefined,此模式可能会有所帮助:

v = { undefined: someValue }[v]; // undefined someValue undefined someValue undefined ...

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

v = +!v;

这将使(给出if if NOT的值符合逻辑然后,我们将返回的布尔值转换为其相应的整数表示形式。vtruev == 0falsev == 1

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

多一个:
v=++v%2

(在C语言中,这很简单++v%=2

ps。是的,我知道这是双重赋值,但这只是C方法的原始重写(按原样工作,因为JS预增量运算符未返回左值)。

如果确保输入为1或0,则可以使用:

v = 2+~v;

定义一个数组{1,0},将v设置为v [v],因此,值为0的v变为1,反之亦然。

v等于任何值的另一种创造性的实现方式将始终返回01

v = !!v^1;

如果v的可能值只有0和1,则对于任何整数x,表达式为:v = Math.pow((Math.pow(x,v)-x),v); 将切换值。

我知道这是一个丑陋的解决方案,OP并没有在寻找这个……但是当我在厕所时,我只是在考虑另一个解决方案:P

未经测试,但是如果您想使用布尔值,我认为var v = !v可以使用。

参考:http//www.jackfranklin.co.uk/blog/2011/05/a-better-way-to-reverse-variables

v=!v;

将适用于v = 0和v = 1; 并切换状态;

如果只有两个值,例如在这种情况下(0,1),我相信使用int是浪费的。而是去布尔值并逐位工作。我知道我在假设,但是在两个状态之间切换的情况下,布尔值似乎是理想的选择。

v =数字(!v)

它将把转换后的布尔值类型转换为Number,这是所需的输出。

好吧,众所周知,在javascript中,布尔比较也将为您提供预期的结果。

v = v == 0足够了。

以下是该代码:

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/

希望这对您有帮助:)

本文地址:http://javascript.askforanswer.com/shifouyougenghaodeshuxiefangshiv-v-010-guanbi.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!