web-dev-qa-db-ja.com

v =(v == 0?1:0);と書くより良い方法はありますか?

変数を0と1の間で切り替えたいです。0の場合は1に設定し、1の場合は0に設定します。

これは非常に基本的な操作であるため、頻繁に書くので、できる限り最短で明確な方法で調査したいと思います。これまでの私のベスト:

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

これを改善できますか?

編集:質問は、明確さを保持しながら、上記のステートメントを最小限の文字で書く方法を尋ねています-これは「実際の質問ではない」ですか?これはコードゴルフの練習を意図したものではありませんでしたが、ゴルフとしてアプローチする人々からいくつかの興味深い答えが出てきました。

456
Ollie Glass

次を使用できます。

v = 1 - v;

もちろん、これは変数が適切に初期化されていること、つまり値が0または1のみであることを前提としています。

より短いが、あまり一般的ではない演算子を使用する別の方法:

v ^= 1;

編集:

明確にするために;私はこの問題にコードゴルフとしてアプローチしたことはありませんでした。オペレーターの副作用のような不明瞭なトリックを使用せずにタスクを実行する短い方法を見つけるためだけです。

702
Guffa

0false値であり、1true値です。

v = (v ? 0 : 1);

数値の代わりにtruefalseを使用して満足している場合

v = !v;

または、数字でなければならない場合:

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

v = (v + 1) % 2そして、さらに値を循環する必要がある場合は、2(n + 1)に変更します。 v = (v + 1) % 3を実行するだけで0、1、2をサイクルする必要があるとします。

199
Prusse

あなたはそれのための関数を書いて、それを次のように使うことができます:

v = inv(v)

75
Daniel

1以外の可能性を気にしない場合:

v = v ? 0 : 1;

上記の場合、vが0、false、undefined、またはnullの場合、vは1になります。この種のアプローチを使用する場合は注意してください-vが「hello world」であっても、vは0になります。

50
Brian

v = 1 - vv ^= 1、またはv= +!vのような行はすべて仕事を成し遂げますが、これらは私がハックと呼ぶものを構成します。これらは美しいコード行ではありませんが、意図した効果を得るための安価なトリックです。 1 - vは「値を0と1の間で切り替える」ことを伝えません。これにより、コードの表現力が低下し、別の開発者がコードを解析する必要のある場所(小さなものですが)が導入されます。

代わりにv = toggle(v)のような関数を使用すると、意図が一目でわかります。

44
Ray

この「回答」に対する投票数を考えると、誠実さと数学的な整合性により、この回答を編集することになりました。 "だから、説明を入れることは目的に反するように思えた。しかし、コメントは、誤解を避けるために明確にするべきであることを明確にしている。

私の元の答え:

仕様のこの部分の文言:

0の場合は1に設定し、それ以外の場合は0に設定します。

最も正確な解決策は次のとおりであることを意味します。

v = dirac_delta(0,v)

まず、告白:I didデルタ関数を混乱させます。クロネッカーデルタはもう少し適切でしたが、ドメインに依存しないものを望んでいたほどではありませんでした(クロネッカーデルタは主に整数にのみ使用されます)。しかし、実際にはデルタ関数を使用すべきではありませんでした、私は言っているべきでした:

v = characteristic_function({0},v)

明確にさせてください。 functionはトリプル(X、Y、f)であることに注意してください。ここでXおよびYはセット(それぞれdomainおよびcodomainと呼ばれます)およびf_ y _の要素を割り当てるルールですXの各要素に。トリプル(X、Y、f)f:X→Yとして書くことがよくあります。 Xのサブセットが与えられた場合、たとえばAの場合、特性関数があり、これは関数χA:X→{0,1}(ℕやasなどのより大きなコドメインへの関数と考えることもできます)。この関数はルールによって定義されます:

χA(x)= 1 if x∈AおよびχA(x)= if x∉Aの場合。

真理値表が好きなら、それは「x of Xサブセットの要素A」という質問に対する真理値表です=? "。

したがって、この定義から、特性関数がここで必要なものであることは明らかです。X 0とA = {0}を含む大きなセットです。それが私がshouldと書いたことです。

そしてデルタ関数にも。そのためには、統合について知る必要があります。既に知っているか、知らないかのどちらかです。そうでない場合、ここで言うことはできませんが、理論の複雑さについては説明しませんが、1文の要約を提供できます。 A measure on a set Xは、本質的に「平均を機能させるために必要なもの」です。つまり、セットにXとメジャーμがあれば、そのクラスには関数のクラスがありますX→ℝ =、呼び出される測定可能な関数の式バツ fdμは理にかなっており、曖昧な意味ではf over Xの「平均」です。

セットのメジャーを指定すると、そのセットのサブセットの「メジャー」を定義できます。これは、サブセットにその特性関数の積分を割り当てることにより行われます(これが測定可能な関数であると仮定します)。これはcan無限、または未定義(2つは微妙に異なります).

周辺には多くの対策がありますが、ここで重要な2つの対策があります。 1つは、実ライン上の標準メジャーです。この測定では、 fdμは、学校で教えられることとほぼ同じです(微積分はまだ学校で教えられますか?):小さな長方形を合計し、ますます幅を小さくします。この測定では、間隔の測定はその幅です。ポイントのメジャーは0です。

any setで機能する別の重要な尺度は、point measureと呼ばれます。関数の積分がその値のsumとなるように定義されています:

バツ fdμ= ∑x∈X f(x)

このメジャーは、各シングルトンセットにメジャー1を割り当てます。これは、サブセットがそれ自体が有限である場合にのみ、finiteメジャーを持つことを意味します。また、有限積分を持つ関数はほとんどありません。関数が有限積分を持つ場合、countableポイント数でのみ非ゼロでなければなりません。そのため、おそらくあなたが知っている大部分の関数は、この測定では有限積分を持ちません。

そして今、デルタ関数に。非常に広い定義を見てみましょう。測定可能な空間(X、μ)(その上にメジャーがあるセットです)と要素a∈Xがあります。 delta functionaに依存)を "定義"して、 "関数" δa:X→ℝδa(x)= if x≠aおよびバツ δa dμ= 1

これに関する最も重要な事実は、これを取得することです:デルタ関数関数である必要はありません。それはnot適切に定義されている:私は何を言っていないδa(a)です。

この時点で何をするかは、あなたが誰であるかによって異なります。ここでの世界は2つのカテゴリに分かれています。あなたが数学者なら、あなたは次のように言います:

さて、デルタ関数が定義されていない可能性があります。その仮想プロパティを見て、それがisで定義されている適切なホームを見つけることができるかどうかを確認しましょう。私たちはそれを行うことができ、最終的にはdistributionsになります。これらはnot(必然的に)関数ですが、関数に少し似た振る舞いをするものであり、関数であるかのように扱うことができます。しかし、それらにはないもの(「値」など)があるので、注意する必要があります。

あなたが数学者でない場合、あなたは次のように言います:

さて、デルタ関数が適切に定義されていない可能性があります。誰がそう言うの?数学者の束?それらを無視してください!彼らは何を知っていますか?

観客を怒らせたので、続けます。

ディラックデルタは、通常、標準メジャーを使用した実ライン上のポイント(多くの場合0)のデルタ関数と見なされます。したがって、私の定義について使用しているので、私のデルタについてわからないというコメントについて不満を言う人はそうしているのです。彼らに謝罪します:数学者の弁護ハンプティダンプティで普及したように:すべてが正しいように再定義するだけで)標準的な用語を使用して別の何かを意味するのは悪い形式です。

しかし、そこにはis私がやりたいことをするデルタ関数があり、それがここで必要なものです。セットでポイント測定を取る場合Xそこにis本物の関数δa :X→ℝこれは、デルタ関数の基準を満たします。これは、関数を探しているためですX→ℝこれはaを除いてゼロであり、そのすべての値の合計が1になるようなものです。そのような関数は単純です:欠落している情報はaの値のみです。合計を1にするには、値1を割り当てます。これは{の特性関数に他なりません。 a}。次に:

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

したがって、この場合、シングルトンセットの場合、特性関数とデルタ関数は一致します。

結論として、ここには「機能」の3つのファミリーがあります。

  1. シングルトンセットの特性関数、
  2. デルタ関数、
  3. クロネッカーのデルタ関数。

これらのsecondは最も一般的です。他のいずれかがポイントメジャーを使用する場合の例です。しかし、1番目と3番目には、常に本物の機能であるという利点があります。 3番目は、特定のドメインファミリー(整数、またはそのサブセット)については、実際には最初の特殊なケースです。

だから、最後に、最初に答えを書いたとき、私はwas n't適切に考えました(私はconfusedであったとは言いませんが、私はちょうど私を実証しましたdo私が実際に最初に考えるときに私が話していることを知っています、私はあまり考えませんでした)。 dirac deltaの通常の意味はここで求められているものではありませんが、私の答えのポイントの1つは、入力ドメインがnotであるため、クロネッカーデルタも正しくなかったことです。したがって、最良の数学答え(私が目指していた)は特性関数でした。

それがすべて明確であることを願っています。また、TeXマクロの代わりにHTMLエンティティを使用して数学的な部分を再度記述する必要がないことも願っています。

40
Loop Space

できる

v = Math.abs(--v);

デクリメントは値を0または-1に設定し、Math.absは-1を+1に変換します。

35
Paul

一般に、2つの値を切り替える必要があるときはいつでも、2つのトグル値の合計から現在の値を差し引くことができます。

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

整数1または0でなければならない場合、括弧は必要ありませんが、それを行う方法は問題ありません。これらをブール値として使用する場合は、次のようにします。

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

十分です!

23
nidhin

ソリューションのリスト

私が提案したい3つの解決策があります。それらはすべて、値を01trueなどの場合)または10falsenullなどの場合)に変換します。

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

そしてもう1つ、既に述べましたが、賢くて高速です(ただし、0sと1sでのみ機能します)。

  • v = 1-v

解決策1

次のソリューションを使用できます。

v = 1*!v

これは最初に整数を反対のブール値に変換し(0Trueに、その他の値をFalseに)、次に1で乗算するときに整数として扱います。その結果、01に、その他の値は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

それは非常にまれであり、常にブール値から整数に変換されます。

18
Tadeck

別の答え、コメント、および私自身の意見をまとめるために、2つのことを組み合わせることをお勧めします。

  1. トグルに関数を使用する
  2. この関数内では、より読みやすい実装を使用します

ライブラリに配置したり、別のJavascriptフレームワークのプラグインにラップしたりできる関数を次に示します。

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

そして、使い方は単純です:

v = inv(v);

利点は次のとおりです。

  1. コードの重複なし
  2. あなたまたは誰かが将来これを再び読んだ場合、あなたは最小限の時間であなたのコードを理解するでしょう。
17

独自のブール値を作成する理由がわかりませんか?ファンキーな構文が好きですが、理解できるコードを書いてみませんか?

これは最短/最速ではありませんが、最も明確な(そして誰もが読める)最も有名なif/else状態を使用しています:

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

本当に明確にしたい場合は、数字の代わりにブール値を使用する必要があります。ほとんどの場合、十分に高速です。ブール値を使用すると、次の構文を使用できます。

v = !v;
13
Mark Knol

元のソリューションの別の形式:

v = Number(v == 0);

編集:元のソリューションのエラーを指摘してくれたTehShrikeとGuffaに感謝します。

12
Kurt Kaylor

もっとはっきりさせたいと思います。

vはどういう意味ですか?

たとえば、vが何らかの状態である場合。オブジェクトのステータスを作成します。 DDDでは値オブジェクト。

この値オブジェクトにロジックを実装します。次に、より機能的な方法でコードを記述し、読みやすくします。ステータスを切り替えるには、現在のステータスに基づいて新しいステータスを作成します。 ifステートメント/ロジックはオブジェクトにカプセル化され、ユニットテストできます。 valueObjectは常に不変であるため、IDはありません。そのため、その値を変更するには、新しい値を作成する必要があります。

例:

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);
11
Marco Franssen

これがありません:

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 ...
10
Nina Scholz

別の方法:

v = ~(v|-v) >>> 31;
10
Eng.Fouad

キックのみ:v = Math.pow(v-1,v)も1と0を切り替えます。

8
Blazemonger

もう1つ:v=++v%2

(Cでは単純な++v%=2になります)

ps。ええ、私はそれが二重の割り当てであることを知っていますが、これはCのメソッドの生の書き直しです(そのままでは機能せず、JSプリインクリメント演算子は左辺値を返しません。

7
Adam Jurczyk

これはJavaScriptであるため、単項+を使用してintに変換できます。

v = +!v;

これにより、NOTの値が論理vになります(v == 0の場合はtruev == 1の場合はfalseが与えられます)。次に、返されたブール値を対応する整数表現に変換します。

7
0x499602D2

配列{1,0}を定義し、vをv [v]に設定します。したがって、値0のvは1になり、その逆も同様です。

7
S..

入力が1または0であることが保証されている場合は、次を使用できます。

v = 2+~v;
7
brandx

vが任意の値に等しい場合の別の創造的な方法は、常に0または1を返します

v = !!v^1;
5
Yanick Rochon

Vの可能な値が0と1のみである場合、整数xについて、式:v = Math.pow((Math.pow(x、v)-x)、v);値を切り替えます。

私はこれがい解決策であることを知っており、OPはこれを探していませんでした...しかし、私はトイレにいたときにちょうど別の解決策を考えていました:P

4
Amit
v=!v;

v = 0およびv = 1で機能します。状態を切り替えます。

3
teacher

テストされていませんが、ブール値を使用している場合は、var v = !vが機能すると思います。

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

3
Martin Bean

この場合(0、1)のように2つの値しかない場合、intを使用するのは無駄だと思います。むしろブール値を使用してビット単位で動作します。私は仮定していることを知っていますが、2つの状態を切り替える場合、ブール値が理想的な選択のようです。

1
Amber

まあ、私たちが知っているように、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/

これを希望するとあなたに役立ちます:)

1
Vikash Pandey

v =数値(!v)

Inverted Boolean値をNumberに型キャストします。これは目的の出力です。

0
Rohit Goyal