ChatGPT解决这个技术问题 Extra ChatGPT

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

关闭。这个问题是基于意见的。它目前不接受答案。想改进这个问题?更新问题,以便可以通过编辑这篇文章用事实和引用来回答它。 3年前关闭。改进这个问题

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

这是一个如此基本的操作,以至于我经常写,我想研究最短、最清晰的方法。这是我迄今为止最好的:

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

你能改进一下吗?

编辑:问题是询问如何在保持清晰的同时用最少的字符编写上述语句 - 这怎么会“不是一个真正的问题”?这并不打算成为一个代码高尔夫练习,尽管一些有趣的答案已经从人们将它当作高尔夫来对待——很高兴看到高尔夫以一种建设性和发人深省的方式被使用。

这对我来说看起来已经很简单/清晰/简短。
诡计:v = +!v;
如果“更好”也意味着“更快”:jsperf.com/v-0-1-0
@Mobinga:+1。这就像它应该得到的一样简单。我看到的所有其他答案都令人困惑,其中一些改变了逻辑;引入错误。
@holodoc 表达您的意见的更好解决方案是创建一个答案,说明您认为原版是最好的方式,并详细说明您为什么会这样。这也允许其他人通过投票轻松地支持您的答案。

G
Guffa

您可以简单地使用:

v = 1 - v;

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

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

v ^= 1;

编辑:

要清楚;我从来没有把这个问题当作代码高尔夫来处理,只是为了找到一种完成任务的捷径,而不使用任何模糊的技巧,比如运算符的副作用。


这些是漂亮的代码行,就像精细切割的玻璃或稀有的开花兰花。我喜欢你如何直接通过逻辑层并直接处理 1 和 0 的数学运算以及可能的最佳操作。我将在我自己的项目中使用这些,但不幸的是,当我需要让同事理解代码时,我将不得不默认使用更基于逻辑的方法。不过谢谢你,你的回答让我很开心。
您可以随时添加注释说明代码的作用。
@Kevin:这显然不能回答所问的问题,这是不正确的。 q 表示“我想在 0 和 1 之间切换一个变量”。一个非常合理的解释是,这意味着变量的值已经是 0 或 1。这种解释/限制在答案中已经明确。你能反对什么?
@Matthew 说我认为没有明确 v ^= 1 的人应该停止编程有点苛刻。如前所述,它不是更常见的运算符之一,它与 v = v ^ 1 的作用不同。运算符在不同语言(VB)中的含义也完全不同。是的,快速查找会告诉你它是一个 XOR 运算符,你会明白它在做什么,但对许多人来说,乍一看可能并不明显。我不认为这意味着你需要辞职。
如果你写这个节省了15个字符,然后用40个字符的评论来解释它,这真的是一种进步吗?
J
Joe

因为 0false 值,而 1true 值。

v = (v ? 0 : 1);

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

v = !v;

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

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

只需将魔术 + 放在 ! 之前。哦,看起来太脏了!但很酷:p
@Quentin - 如果他有 switch(v){ case 0 ... 或 if(v == 0) 或 v === 0,这将破坏他的代码。除了他的方法之外,你正在改变他的结果......
开个笑脸:({v :+! v}).v
@Brian:没有那个神奇的 + 标志! ¯\_(ツ)_/¯
v = (v ? 0 : 1) +1 作为清晰和惯用的 JS。
P
Prusse

v = (v + 1) % 2,如果您需要循环显示更多值,只需将 2 更改为 (n + 1)。假设您需要循环 0、1、2,只需执行 v = (v + 1) % 3


我喜欢循环!这真的很聪明。
+1 将切换视为一个循环。考虑到它的灵活性很简单。
+1 用于提供同样强大的模块化解决方案。在实践中,您可能希望使用 const 变量来代替幻数 2、3、...
更短(hackier)的方式:++v % 3 如果你想循环通过 0、1、2
D
Daniel

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

v = inv(v)


+1我强烈同意这是最干净的解决方案(......但是inv函数中的内容:P)
我希望我能给这个答案不仅仅是+1。如果通用代码不是很明显,则应将其包装在具有描述性名称的函数中。
@TehShrike 您认为 inv 是一个描述性名称吗?
@Bennett McElwee:inv = 反转。对我来说,这似乎是一个常见的缩写。
那么为什么要缩写它,称它为“反转”或“切换”并让代码可读。我们并不是想把这些东西装到一张 80 列的穿孔卡片上。
B
Brian

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

v = v ? 0 : 1;

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


那不会翻转价值。你的意思是v = v ? 0 : 1
@Guffa - +1 发现我的阅读障碍......
这是我最喜欢的基于逻辑的答案,我可以和同事一起使用(我看到@Guffa 的答案是基于数字的)。我喜欢你如何进行不必要的测试 (v==0) 和括号,将其剥离到绝对最小字符数。谢谢你。
我也是@Guffa 回答的忠实粉丝——用 lynard skynard 的话来说,保持简单;)
+1 用于理解“真实”的价值观。
R
Ray

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

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


-1,说真的,v=1-v 没有传达开关?
1-v 确实可以交流切换,但这是它交流的唯一内容。例如,它还可以在 v=1 处传达一条为零的线,或以 v=0.5 为中心的镜像变换。从这个意义上说,它是相对模棱两可的。确实,知道 v 只能是 01 会限制其预期含义,但这会迫使其他开发人员(或您未来的自己)在能够理解这个简单的行之前理解该上下文。你再清楚不过了 v = toggle(v)
但是,如果您了解逻辑操作,v ^= 1 就非常清楚,如果您是程序员,则最好这样做。我认为这就是那和 v=1-v 之间的区别;一个是逻辑运算,一个是算术运算,我们试图表示一个逻辑概念而不是数学概念。
@Matthew Read:这是一个很好的声明,很好地总结了我的想法:“我们试图代表一个逻辑概念而不是数学概念。”但是,即使 v ^= 1 也有一些歧义,因为它可以解释为按位异或。
对于程序员(是的,我的意思是像我们这样的极客),这些非常清楚。它们不是黑客,因为它们的简单性是优雅的解决方案。
A
Andrew Stacey

(诚实和数学上的完整性——考虑到这个“答案”的投票数——让我编辑了这个答案。我尽可能地推迟了,因为它是一个简短的俏皮话,而不是任何“深刻”的东西,所以放进去任何解释似乎都与目的背道而驰。但是,评论清楚地表明我应该清楚以避免误解。)

我原来的答案:

这部分规范的措辞:

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

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

v = dirac_delta(0,v)

首先,坦白:我确实把我的 delta 函数弄糊涂了。 Kronecker delta 会稍微合适一些,但并不像我想要的那样与域无关(Kronecker delta 主要用于整数)。但我真的根本不应该使用 delta 函数,我应该说:

v = characteristic_function({0},v)

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

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

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

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

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

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

周围有很多措施,但这里有两个很重要。一种是实线上的标准度量,ℝ。对于这个度量,那么 ∫ℝ f dμ 几乎就是你在学校学到的东西(微积分还在学校教吗?):总结小矩形并取越来越小的宽度。在这个度量中,间隔的度量是它的宽度。一个点的度量是0。

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

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

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

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

要掌握的最重要的事实是:delta 函数不必是函数。它没有正确定义:我没有说 δa(a) 是什么。

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

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

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

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

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

狄拉克 delta 通常被认为是实线中一个点(通常为 0)与其标准度量的 delta 函数。所以那些在评论中抱怨我不知道我的增量的人这样做是因为他们使用了这个定义。向他们道歉:虽然我可以通过使用数学家的辩护(正如 Humpty Dumpty 所推广的那样:简单地重新定义一切以使其正确)来摆脱这种情况,但使用标准术语来表示不同的东西是不好的形式。

但是有一个 delta 函数可以做我想做的事情,这就是我需要的。如果我对集合 X 进行点测量,则存在一个真正的函数 δa : X → ℝ,它满足 delta 函数的标准。这是因为我们正在寻找一个函数 X → ℝ,它除了在 a 和之外为零,使得它的所有值的总和为 1。这样的函数很简单:唯一缺少的信息是它在 a 处的值,并且为了使总和为 1,我们只需为其赋值 1。这正是 {a} 上的特征函数。然后:

∫X δa dμ = ∑x ∈ X δa(x) = δa(a) = 1。

所以在这种情况下,对于单例集,特征函数和增量函数是一致的。

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

单例集的特征函数,三角函数,克罗内克三角函数。

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

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

我希望这一切都清楚;我也希望我再也不用用 HTML 实体而不是 TeX 宏来写数学文章了!


+1 - 如果我可以因为不知道 dirac_delta 函数而对 Quentin 投反对票。我想知道他上的是哪所大学,因为如果他们甚至不知道数字处理的基础知识,我认为我不会从那里雇用任何人。我会进一步否决昆汀,因为他无法理解你所尝试的幽默。
如果我对我不理解的每个答案都投了反对票……我会反对很多答案。
你好安德鲁,已经有一段时间了。
@Tim:天哪,原来如此!百慕大主教怎么样? (我记得对吗?)我想这个评论帖子不是追赶的最佳地点,虽然...... 17 年,不是吗?
@Cԃաԃ“这个答案失败了......”叹息。你确实读到我是个数学家,不是吗?这个答案非常适合真空中的球形程序员,所以我不知道你在抱怨什么。
M
Mouna Cheikhna

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

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


这是有趣和有创意的,但有潜在的危险。如果 v 损坏,它将突然开始在两个不同的值之间切换。 (只是需要考虑的事情......)
+1 有趣的想法。并不是说 OP 或其他任何人实际上会在这种情况下使用它,但这条信息应该永远存在于大脑的某个地方。
@oosterwal:那么问题肯定在于腐败......
@GManNickG:迟早会发生数据损坏,因此我们需要了解未检测到它的后果。如果 v 通常用于从三个或更多状态的列表中交替执行两个状态,则 v 的损坏可能导致程序交替执行两个完全不同的状态 - 这可能会导致意外和不希望的结果。从中吸取的教训是:始终对您的数据进行合理性检查。
p
pimvdb

你可以做

v = Math.abs(--v);

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


这已经变成了“生成 10000 种方法来完成简单任务”的竞赛。我喜欢所有的方式哈哈。
v = Math.round(Math.sin(Math.PI/(v+3)));
@Benoit - 对于 v=0 和 v=1,您的公式等于 1。 一个是正确的! v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));:D
那永远不会改变价值。如果 v = 1v = Math.Abs(-1) 即 +1。如果 v = 0v = Math.Abs(-0) 为 0。
+1这是我的另一个...... Grr。
M
Michael Berkowski

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

v = !v;

这不会导致 Ollie 的“v”被设置为布尔结果,而不是整数吗?
是的,它会的,我在代码行上方的句子中警告过这一点。如果将这些 a 用作布尔值
n
nidhin
v = v == 0 ? 1 : 0;

足够的 !


与其说是答案,不如说是意见,你不觉得吗?
@Brian:“更好”实际上是关于意见。
我喜欢你把括号去掉的方式——去掉了几个字符!
@Brian:“答案”是“不,没有更好的写法v = (v==0 ? 1 : 0);。其他人都在寻找不同的打高尔夫球方式。并没有真正回答这个问题。这就是为什么我投票赞成这个答案。
T
Tadeck

解决方案列表

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

v = 1*!v

v = +!v

v = ~~!v

以及另外一个,已经提到过,但聪明且快速(虽然仅适用于 0s 和 1s):

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

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


在 JavaScript 中,您可以在变量前加上 + 以将其转换为数字,因此 +!v 等效于您的解决方案(OP 评论中的 jAndy 解决方案)。
@mblase75:是的,当尝试将布尔值转换为整数时,1* 可以替换为 + 是对的。我的答案中的其他所有内容都保持不变。 jAndy 的回答是正确的,但我的回答更详细。我会将他/她的解决方案添加到我的答案中。
@Tadeck +1 的好主意。
M
Martin Schlagnitweit

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

使用切换函数在此函数内部使用更易读的实现

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

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

用法很简单:

v = inv(v);

优点是:

无代码重复 如果您或任何人将来再次阅读此内容,您将在最短的时间内理解您的代码。


他们是吗?我进行了一个快速测试:jsperf.com/function-vs-no-function/2,看起来差异并没有那么大。
7.5ns 与 8.8ns。额外的 1.3 纳秒真的会杀死你。
用我节省的所有时间,我带我的家人去迪斯尼世界! :-)
完全正确。编写“聪明”解决方案的人可能永远不必维护其他程序员的代码“宝石”
为什么不function toggle(i){ return i == 0 ? 1 : 0 }
N
Nina Scholz

这是缺少的:

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 ...

你能解释答案吗,可能用 jsfiddle (或等效的)?
@Phalgun,什么部分?你可以自己试试...
我正在尝试插入一些数字来测试它。例如,考虑 v = 7,那么对于 OP 的答案 v = (v == 0 ? 1 : 0),v 是 0。现在,对于 v = [1, 0][v],v 是未定义的。我想我在这里遗漏了一些东西。
您需要声明 v 并取 01 的值。
并不真地。如果您采用 +!v(如答案 below),则不再需要 array ,因为您已经获得了值。在我的示例中使用 v 而不转换为另一个值或类型。
c
c69

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

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

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

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

v = !v;

这实际上是我的首选答案;但是 三元运算符 vs if-else 是一场圣战,我不想点燃导火索。也就是说,我认为第一行应该是 === 0。对于 7 的样本输入,正确的输出是 0,但这将输出 1
默默地纠正像 7 这样的输入而不是抛出某种异常是否有价值?我的意思是,如果在您的代码更正值之前,其他一些代码在它只期望 0 或 1 时得到了 7 怎么办?
佚名

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

v = Number(v == 0);

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


== 运算符在许多系统下返回一个布尔值(而不是整数)。这只有在 v 被定义为整数时才有效,并且语言很酷,可以自动从布尔值转换为整数。
非常真实。我在 javascript 的上下文中回答了这个问题(如何标记问题)。
@Kurt Kaylor:Javascript 是 == 运算符返回布尔值的系统之一,因此它与原始解决方案的作用不同。
@Guffa:我正在利用 javascript 是一种具有隐式类型转换的弱类型语言(例如'0.0000' == 0, 0 == "", false == "", false == 0, 1 ==真的,等等)。我可以像使用整数 0 或 1 一样使用返回的布尔值。例如,尝试在 javascript 控制台中评估“2 + true”,你会得到 3。
@Kurt Kaylor:这只适用于强制进行隐式转换的情况。尝试以 'opacity:'+true 为例,您最终会得到 opacity:true 而不是 opacity:1
M
Marco

我会让它更明确。

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);

超过工程?
+1 让我发笑
D
David G

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

v = +!v;

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


E
Eng.Fouad

另一种方法:

v = ~(v|-v) >>> 31;

A
Adam Jurczyk

还有一个:v=++v%2

(在 C 中很简单 ++v%=2

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


你的 C 版本是非法的;您不能修改 ++ 运算符的结果(它不是左值)。至于 v=++v%2,您修改了 v 两次。我不知道这在 JavaScript 中是否定义得很好,但这不是必需的。 v = (v+1) % 2
至少在 c++ 中是 - 因为预增量运算符具有更高的优先级并“就地”修改变量,所以它可以用作左值。我认为 ++ 的 JS 实现不能被视为左值:/ 是的,这是多余的,但我试图展示另一种方法 - 已经发布了更好的解决方案 :)
+1。可以写成 v = (v+1)%2。
b
brandx

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

v = 2+~v;

B
Blazemonger

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


S
S..

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


我的解决方案是正确的,如果您不喜欢,请写下原因。您的评论对任何人都没有帮助。我的解决方案读取一个变量,而不是做出决定。这需要更少的 CPU。
Y
Yanick Rochon

另一种创造性的做法,即 v 等于任何值,将始终返回 01

v = !!v^1;

两个 !! 不会在逻辑数学中产生任何结果,您可以将 !!!! 放在那里并且会相同,但会产生 4 个不需要的操作
@Alex:!! 将转换为布尔值。 !!(1) === true!!(0) === false
@nickf:啊哈,所以我想 v = Boolean(v^1) 会提供更多信息,感谢您的解释 - 没想过选角
@Alex,“逻辑数学”?这就是为什么数学家是差劲的程序员。不要误会我的意思;好的程序员也善于理解数学。但这与逻辑数学无关。这是一种语言结构,给定任何表达式,至少在 Javascript 中,! 会将其转换为布尔值。添加另一个 ! 将否定该布尔值。强制转换在这里是隐式的,最终结果有效。不需要-1。
我根本不是数学家。你可以试试这个看看自己jsperf.com/javascript-boolean-test
A
Amit

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

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


M
Martin Bean

未经测试,但如果您使用布尔值,我认为 var v = !v 会起作用。

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


t
teacher
v=!v;

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


A
Amber

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


R
Rohit Goyal

v = 数字(!v)

它将反转布尔值类型转换为数字,这是所需的输出。


a
ankitkanojia

好吧,正如我们所知,在 javascript 中,只有布尔比较也会给你预期的结果。

v = v == 0 就足够了。

下面是代码:

变量 v = 0; alert("如果 v 为 0 输出:" + (v == 0)); setTimeout(function() { v = 1; alert("如果 v 为 1 输出:" + (v == 0)); }, 1000);

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

希望这会帮助你:)


这适用于切换值,但该值不会在 0 和 1 之间切换,而是在 truefalse 之间切换。您可以使用 v == 0 来确定条件中变量的值,但如果您想使用值 0 或 1,则需要使用 v == 0 ? 0 : 1Number(v) 之类的东西来获得它。 (此外,您可以使用 v = !v;truefalse 之间切换。)
是的。。谢谢你:)