有没有更好的v = (v == 0)的写法?1: 0);

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

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

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

你能改进一下吗?

编辑:这个问题问的是如何在保持清晰的情况下用最少的字符写出上面的语句——为什么这“不是一个真正的问题”?这并不是一个代码-高尔夫练习,尽管一些有趣的答案来自于把它当作高尔夫的人——很高兴看到高尔夫以一种建设性和发人深省的方式被使用。

75856 次浏览
v = v == 0 ? 1 : 0;

够了!

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

v = inv(v)

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

v = !v;

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

v = v ? 0 : 1;

在上述情况下,如果v为0、false、undefined或null, v将最终为1。注意使用这种方法-即使v是"hello world", v也将为0。

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

v = (v ? 0 : 1);

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

v = !v;

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

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

你可以简单地使用:

v = 1 - v;

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

另一种方法更短,但使用了不太常见的操作符:

v ^= 1;

编辑:

清楚:清楚;我从来没有把这个问题作为代码高尔夫来处理,只是为了找到一种不使用任何模糊技巧(如操作符的副作用)的简单方法来完成任务。

v = (v + 1) % 2,如果你需要循环更多的值,只需改变(n + 1)2。假设你需要循环0、1、2,只需执行v = (v + 1) % 3

你可以这样做

v = Math.abs(--v);

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

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

相反,使用像v = toggle(v)这样的函数可以最快速地传达意图。

另一种创造性的方法是,v等于任何值,将总是返回01

v = !!v^1;

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

v = Number(v == 0);

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

< p >一个: v=++v%2 < / p >

(在C语言中,它将是简单的++v%=2)

ps.是的,我知道这是双赋值,但这只是C的方法的原始重写(它不工作,因为JS的前增量操作符不返回左值。

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

  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;

(诚实和数学上的完整性——考虑到这个“答案”的投票数量——促使我编辑这个答案。我尽可能长时间地拖延,因为这是一个简短的讽刺,而不是任何“深刻”的东西,所以任何解释似乎都与目的背道而驰。然而,这些评论清楚地表明,我应该清楚地避免误解。)

我最初的回答是:

这部分规范的措辞:

如果是0,就设为1,否则设为0。

这意味着最准确的解是:

v = dirac_delta(0,v)

首先,坦白:我做了弄混了函数。Kronecker delta可能会稍微更合适一些,但并不像我想要的那样是域独立的(Kronecker delta主要用于整数)。但我真的不应该用函数,我应该说

v = characteristic_function({0},v)

让我澄清一下。回忆一下,函数是一个三元组(X, Y, f),其中XY是集合(分别称为),而f是一个规则,将Y的元素赋值给X的每个元素。我们通常将三元(X, Y, f)写成(X, Y, f)0。给定X的一个子集,比如(X, Y, f)2,有一个(X, Y, f)3,它是一个函数(X, Y, f)4(它也可以被认为是一个更大的上域的函数,如ℕ或ℝ)。该函数由如下规则定义:

如果是x活动内容;一个则为A(x) = 1,如果是x ∉一个则为A(x) = 0

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

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

对于函数。为此,我们需要了解积分。你要么已经知道,要么还不知道。如果你不知道,我在这里说什么也不能告诉你这个理论的复杂性,但我可以给一个一句话的总结。集合X上的测量本质上是“使平均值生效所需的东西”。也就是说,如果我们有一个集合X和该集合上的测度μ;,那么就有一类函数X →ℝ,称为可测函数,其中表达式X f dμ是有意义的,在某种模糊的意义上,它是f除以X的“平均值”。

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

有很多衡量标准,但这里有两个是重要的。一个是实行的标准测量, ℝ对于这个度量,那么几乎就是你在学校里学到的东西(学校里还教微积分吗?):把小矩形加起来,取越来越小的宽度。在这个度量中,间隔的度量是它的宽度。点的度数是0。

另一个在任何集上工作的重要度量称为点测量。它的定义使得函数的积分是其值的总和:

X f dμ= ∑x ∈ x f(x)

这个度量值分配给每个单例集度量值1。这意味着一个子集具有有限的度量当且仅当它本身是有限的。很少有函数的积分是有限的。如果一个函数有一个有限积分,它必须只有在可数名词个数的点上非零。所以你们可能知道的绝大多数函数在这种方法下都没有有限积分。

现在来看函数。让我们用一个非常宽泛的定义。我们有一个可测量的空间(X,μ,)(所以这是一个有测量值的集合)和一个元素活动内容;X。我们将δ函数(取决于一个)“定义”为“函数”δa: X &right tarrow;ℝ,其属性为δ< >a(x) = 0如果x东北;一个X δa dμ= 1

关于这个最重要的事实是:函数不一定是函数。它是正确定义的:我没有说三角洲;<子> < /子> (a)是什么。

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

所以函数可能没有定义。让我们看看它的假设属性,看看我们是否可以为它找到一个合适的家,在定义的地方。我们可以这样做,最后得到分布。这些是(必然)函数,但它们的行为有点像函数,我们通常可以把它们当作函数来使用;但有些东西是他们不具备的(比如“价值观”),所以我们需要小心。

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

所以函数可能没有正确定义。谁这么说的?一群数学家?忽略他们!他们知道什么?

既然冒犯了我的听众,我将继续。

狄拉克δ通常被认为是点(通常为0)在实线与其标准测度的函数。所以那些在评论中抱怨我不知道我的delta的人这样做是因为他们使用了这个定义。对他们,我道歉:虽然我可以通过使用数学家的国防(由汉仆。达谱普及:简单地重新定义一切,使其正确)来摆脱这一点,但使用标准术语来表示不同的东西是不好的形式。

但是有一个函数,它做了我想要它做的事情,它是我在这里需要的。如果我在集合X上取点测量,那么就有一个真正的函数δa: X &right tarrow;ℝ,它满足函数的条件。这是因为我们正在寻找一个函数X →ℝ,该函数除一个外为零,并且其所有值的和为1。这样的函数很简单:唯一缺少的信息是它在一个处的值,为了使和为1,我们只需将值赋给它1。这不是别人,正是{一}上的特征函数。然后:

X δa dμ= ∑x ∈X < /订阅>δ;<子> < /子> (X) =δ;<子> < /子> (a) = 1。

在这种情况下,对于一个单一集合,特征函数和函数是一致的。

总之,这里有三种“函数”:

  1. 单例集的特征函数,
  2. 函数,
  3. 克罗内克函数。

其中第二个是最通用的,因为其他任何一个都是它在使用点测量时的一个例子。但第一个和第三个的优点是它们总是真正的函数。第三种实际上是第一种的特殊情况,适用于一组特定的域(整数或其某个子集)。

所以,最后,当我最初写答案时,我不是思考正确(我不会说我是困惑,因为我希望我只是证明了我知道我在说什么,当我真正思考的时候,我只是没有想太多)。狄拉克delta的通常含义不是这里想要的,但我的答案的一个要点是,输入域是定义的,所以克罗内克delta也不正确。因此,最好的数学答案(我的目标)将是特征函数。

我希望大家都明白了;我也希望我再也不用用HTML实体而不是TeX宏来写一篇数学文章!

未经测试,但如果你是布尔,我认为var v = !v将工作。

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

一般来说,当你需要在两个值之间切换时,你可以从两个切换值的和中减去当前值:

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

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

v = 2+~v;

我会说得更清楚一点。

v是什么意思?

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

在这个值对象中实现逻辑。这样你就可以以更实用的方式编写代码,从而更易于阅读。切换状态可以在当前状态的基础上创建一个新的status。然后,你的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的可能值只有0和1,则对于任意整数x,表达式为: v = Math.pow((Math。Pow (x, v) - x), v);

我知道这是一个丑陋的解决方案,而且OP并没有想要这个…但我在厕所的时候想到了另一个解决方案:P

解决方案列表

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

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

还有一个额外的,已经提到过,但聪明和快速(尽管只适用于__abc0和__abc1):

  • v = 1-v

解决方案1

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

v = 1*!v

这将首先将整数转换为相反的布尔值(0转换为True,任何其他值转换为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 = ~(v|-v) >>> 31;

只是为了好玩:v = Math.pow(v-1,v)也在1和0之间切换。

v=!v;

对于v=0和v=1都成立;切换状态;

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

如果只有两个值,如本例中的(0,1),我认为使用int是浪费的。宁愿用布尔值,用比特来计算。我知道我在假设,但在两种状态之间切换布尔似乎是理想的选择。

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

v = +!v;

这将从逻辑上NOT v的值(如果v == 0则给出true,如果v == 1则给出false)。然后将返回的布尔值转换为相应的整数表示。

这是缺失的:

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中只有布尔比较也会给你预期的结果。

例如,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/

希望这将帮助你:)

v = !v * 1

乘以1将布尔值转换为数字

v = Number(!v)

它将反向布尔值类型转换为Number,这是期望的输出。