Apakah ada cara menulis yang lebih baik v = (v == 0? 1: 0); [Tutup]

465

Saya ingin mengaktifkan variabel antara 0 dan 1. Jika 0, saya ingin mengaturnya ke 1, kalau tidak 1 saya ingin mengaturnya ke 0.

Ini adalah operasi mendasar yang saya tulis sangat sering sehingga saya ingin menyelidiki cara yang sesingkat dan sejelas mungkin untuk melakukannya. Inilah yang terbaik sejauh ini:

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

Bisakah Anda memperbaiki ini?

Sunting: pertanyaannya adalah bertanya bagaimana menulis pernyataan di atas dalam karakter paling sedikit sambil mempertahankan kejelasan - bagaimana ini 'bukan pertanyaan yang sebenarnya'? Ini tidak dimaksudkan untuk menjadi latihan kode-golf, meskipun beberapa jawaban menarik telah datang dari orang-orang yang mendekatinya sebagai golf - senang melihat golf digunakan dengan cara yang konstruktif dan merangsang pikiran.

Kaca Ollie
sumber
20
Ini sudah terlihat sederhana / jelas / singkat bagi saya.
Mob
136
tipu daya:v = +!v;
jAndy
48
Jika 'lebih baik' juga berarti 'lebih cepat': jsperf.com/v-0-1-0 .
pimvdb
7
@Mobinga: +1. Ini semudah yang seharusnya. Semua jawaban lain yang saya lihat membingungkan, dan beberapa dari mereka mengubah logikanya; memperkenalkan bug.
Ian Boyd
8
@holodoc Solusi yang lebih baik untuk mengutarakan pendapat Anda adalah dengan membuat jawaban yang mengatakan bahwa Anda merasa yang asli adalah cara terbaik, dan jelaskan MENGAPA Anda merasa itulah masalahnya. yang juga memungkinkan orang lain dengan mudah memihak jawaban Anda dengan memilihnya.
Chuck van der Linden

Jawaban:

721

Anda cukup menggunakan:

v = 1 - v;

Ini tentu saja mengasumsikan bahwa variabel diinisialisasi dengan benar, yaitu hanya memiliki nilai 0 atau 1.

Metode lain yang lebih pendek tetapi menggunakan operator yang kurang umum:

v ^= 1;

Edit:

Untuk lebih jelas; Saya tidak pernah mendekati pertanyaan ini sebagai kode golf, hanya untuk menemukan cara singkat dalam melakukan tugas tanpa menggunakan trik yang tidak jelas seperti efek samping operator.

Guffa
sumber
206
Ini adalah baris kode yang indah, seperti gelas yang dipotong halus atau anggrek berbunga langka. Saya suka bagaimana Anda mencapai langsung melalui lapisan logis dan berurusan langsung dengan matematika 1 dan 0 dengan operasi paling optimal. Saya akan menggunakan ini dalam proyek saya sendiri, tetapi sayangnya ketika saya membutuhkan kode untuk dipahami oleh rekan kerja saya harus default ke pendekatan yang lebih berbasis logika. Terima kasih, jawaban Anda telah membuat saya senang.
Ollie Glass
37
Anda selalu dapat menambahkan komentar yang mengatakan apa yang dilakukan kode.
Prusse
25
@ Kevin: Tidak benar bahwa ini jelas tidak menjawab pertanyaan yang ditanyakan. Q mengatakan "Saya ingin beralih variabel antara 0 dan 1." Penafsiran yang sangat masuk akal adalah bahwa ini menyiratkan bahwa nilai variabel sudah 0 atau 1. Penafsiran / batasan ini dibuat eksplisit dalam jawabannya. Di dunia apa Anda bisa keberatan?
LarsH
50
@ Matius untuk mengatakan bahwa seseorang yang tidak menemukan v ^= 1harus berhenti pemrograman agak kasar saya pikir. Seperti yang dinyatakan sebelumnya itu bukan salah satu operator yang lebih umum dan tidak melakukan hal yang sama v = v ^ 1. Juga operator berarti sesuatu yang sama sekali berbeda dalam bahasa yang berbeda (VB). Ya, pencarian cepat akan memberi tahu Anda bahwa ini adalah operator XOR dan Anda akan mengerti apa yang dilakukannya, tetapi bagi banyak orang mungkin tidak jelas pada pandangan pertama. Saya tidak berpikir itu berarti Anda harus keluar dari pekerjaan Anda.
JD Isaacks
80
Jika Anda menyimpan 15 karakter dengan menulis ini tetapi kemudian menggunakan 40 karakter komentar untuk menjelaskannya, apakah ini benar-benar perbaikan?
Michael Myers
343

Karena itu 0adalah falsenilai dan 1adalah truenilai.

v = (v ? 0 : 1);

Jika Anda senang menggunakan truedan falsebukannya angka

v = !v;

atau jika harus berupa angka:

v = +!v; /* Boolean invert v then cast back to a Number */
Quentin
sumber
55
letakkan saja sihir +sebelum itu !. Ohhh itu terlihat sangat kotor! but cool: p
jAndy
1
@ Quentin - ini akan memecahkan kode orang itu jika dia memiliki switch(v){ case 0 ...atau jika (v == 0) atau jika v === 0. Anda mengubah hasilnya selain pendekatannya ....
Brian
34
Membuat smiley itu: ({v :+! v}).v.
pimvdb
17
@ Brian: tidak dengan +tanda ajaib itu ! ¯ \ _ (ツ) _ / ¯
jAndy
11
+1 untuk v = (v ? 0 : 1)JS yang jelas dan idiomatis.
Bennett McElwee
200

v = (v + 1) % 2dan jika Anda perlu untuk siklus melalui nilai lebih hanya mengubah 2untuk (n + 1). Katakanlah Anda perlu siklus 0,1,2 lakukan saja v = (v + 1) % 3.

Prusse
sumber
2
Saya suka siklusnya! Itu sangat pintar.
Ollie Glass
16
+1 untuk berpikir tentang sakelar sebagai sebuah siklus. Sederhana mengingat betapa fleksibelnya itu.
Guffa
3
+1 untuk memberikan solusi modular yang juga tangguh. Dalam praktiknya, Anda mungkin ingin menggunakan constvariabel sebagai pengganti angka ajaib 2, 3, ...
oosterwal
2
Cara yang lebih pendek (peretas): ++v % 3jika Anda ingin menggilir 0, 1, 2
haraldmartin
75

Anda dapat menulis fungsi untuk itu dan menggunakannya seperti:

v = inv(v)

Daniel
sumber
30
+1 Saya sangat setuju ini adalah solusi terbersih (... tapi kemudian apa yang ada di invfungsi: P)
Lea Hayes
4
Saya berharap bisa memberikan jawaban ini lebih dari sekedar +1. Jika kode umum tidak terlalu jelas, kode itu harus dibungkus dengan fungsi dengan nama deskriptif.
TehShrike
11
@TehShrike yang Anda anggap invsebagai nama deskriptif?
Bennett McElwee
3
@Bennett McElwee: inv = invert. Selalu tampak seperti singkatan umum bagi saya.
Daniel
51
Mengapa menyingkatnya kemudian, menyebutnya 'terbalik' atau 'beralih' dan minta kode itu dapat dibaca. itu bukan seolah-olah kita mencoba untuk memasukkan barang-barang ini ke kartu punch 80 kolom atau sesuatu.
Chuck van der Linden
50

Jika Anda tidak peduli dengan kemungkinan selain 1:

v = v ? 0 : 1;

Dalam kasus di atas, v akan menjadi 1 jika v adalah 0, salah, tidak terdefinisi atau nol. Hati-hati menggunakan pendekatan semacam ini - v akan menjadi 0 bahkan jika v adalah "hello world".

Brian
sumber
2
Itu tidak akan membalik nilainya. Maksudmu v = v ? 0 : 1.
Guffa
3
@Guffa - +1 untuk menangkap disleksia saya ...
Brian
3
Ini adalah jawaban berbasis logika favorit saya yang dapat saya gunakan dengan rekan kerja (Saya melihat jawaban @ Guffa sebagai berbasis angka). Saya suka bagaimana Anda telah mengambil tes yang tidak perlu (v == 0) dan tanda kurung, mengupasnya ke jumlah karakter minimum absolut. Terima kasih.
Ollie Glass
1
Saya penggemar berat jawaban @ Guffa juga - dalam kata-kata lynard skynard, jaga tetap sederhana;)
Brian
2
+1 untuk memahami nilai-nilai "kebenaran".
zzzzBov
44

Garis suka v = 1 - v, atau v ^= 1atau v= +!vakan semua mendapatkan pekerjaan yang dilakukan, tetapi mereka merupakan apa yang saya sebut sebagai hacks. Ini bukan baris kode yang indah, tetapi trik murah untuk mendapatkan efek yang diinginkan. 1 - vtidak berkomunikasi "toggle nilai antara 0 dan 1". Ini membuat kode Anda kurang ekspresif dan memperkenalkan tempat (meskipun kecil) tempat pengembang lain harus menguraikan kode Anda.

Sebagai gantinya memiliki fungsi seperti v = toggle(v)mengomunikasikan maksud dengan cepat.

sinar
sumber
8
-1, serius, v=1-vtidak mengomunikasikan beralih?
Blindy
22
1-vmemang bisa berkomunikasi toggle, tapi hanya itu yang berkomunikasi. Misalnya, ia juga dapat mengkomunikasikan garis dengan nol at v=1, atau transformasi mirroring yang berpusat di v=0.5. Dalam pengertian ini relatif tidak jelas. Memang benar bahwa mengetahui itu vhanya bisa 0atau 1membatasi makna yang dimaksudkan, tetapi itu memaksa pengembang lain (atau diri Anda di masa depan) untuk memahami konteks itu sebelum dapat memahami garis sederhana ini. Anda tidak bisa lebih jelas dariv = toggle(v)
Ray
10
v ^= 1sangat jelas jika Anda memahami operasi logis, yang lebih baik jika Anda seorang programmer. Saya pikir itulah perbedaan antara itu dan v=1-v; satu operasi logis dan satu operasi aritmatika, dan kami berusaha untuk mewakili konsep logis bukan konsep matematika.
Matius Baca
6
@Matthew Read: Ini adalah pernyataan yang bagus, yang meringkas pikiran saya dengan baik: "kami mencoba untuk mewakili konsep logis bukan yang matematis." Bahkan v ^= 1memiliki beberapa ambiguitas, karena dapat ditafsirkan sebagai bitwise-xor.
Ray
6
untuk programmer (dan ya, maksud saya geeks seperti kita), ini cukup jelas. Mereka bukan peretasan, karena mereka solusi elegan karena kesederhanaannya.
gion_13
38

( Kejujuran dan integritas matematis - mengingat jumlah suara pada "jawaban" ini - telah mengarahkan saya untuk mengedit jawaban ini. Saya menahan selama mungkin karena itu dimaksudkan sebagai gurauan singkat dan bukan sebagai sesuatu yang "dalam" sehingga memasukkan penjelasan apa pun tampaknya bertentangan dengan tujuan. Namun, komentar tersebut menjelaskan bahwa saya harus jelas untuk menghindari kesalahpahaman. )

Jawaban asli saya:

Kata-kata dari bagian spesifikasi ini:

Jika 0, saya ingin mengaturnya ke 1, atau atur ke 0.

menyiratkan bahwa solusi yang paling akurat adalah:

v = dirac_delta(0,v)

Pertama, pengakuan: Saya memang bingung fungsi delta saya. Delta Kronecker akan sedikit lebih tepat, tetapi tidak sebanyak yang saya inginkan dari sesuatu yang bebas domain (delta Kronecker terutama digunakan hanya untuk bilangan bulat). Tapi saya seharusnya tidak menggunakan fungsi delta sama sekali, saya seharusnya mengatakan:

v = characteristic_function({0},v)

Izinkan saya mengklarifikasi. Ingat bahwa fungsi adalah triple, (X, Y, f) , di mana X dan Y adalah set (disebut domain dan kodomain masing-masing) dan f adalah aturan yang ditunjuk unsur Y untuk setiap elemen X . Kami sering menulis triple (X, Y, f) sebagai f: X → Y . Diberikan subset dari X , katakanlah A , ada fungsi karakteristik yang merupakan fungsi χ A : X → {0,1}(itu juga dapat dianggap sebagai fungsi untuk codomain yang lebih besar seperti ℕ atau ℝ). Fungsi ini ditentukan oleh aturan:

χ A (x) = 1 jika x ∈ A dan χ A (x) = 0 jika x ∉ A .

Jika Anda menyukai tabel kebenaran, ini adalah tabel kebenaran untuk pertanyaan "Apakah elemen x dari X merupakan elemen dari subset A ?".

Jadi dari definisi ini, jelas bahwa fungsi karakteristik adalah apa yang diperlukan di sini, dengan X set besar berisi 0 dan A = {0} . Itu yang seharusnya saya tulis.

Dan begitu juga untuk delta fungsi. Untuk ini, kita perlu tahu tentang integrasi. Entah Anda sudah mengetahuinya, atau tidak. Jika tidak, tidak ada yang bisa saya katakan di sini yang akan memberi tahu Anda tentang seluk beluk teori ini, tetapi saya bisa memberikan ringkasan satu kalimat. Sebuah ukuran pada set X pada dasarnya "apa yang diperlukan untuk membuat rata-rata bekerja". Dengan kata lain, jika kita memiliki himpunan X dan ukuran μ pada himpunan itu maka ada kelas fungsi X → ℝ , yang disebut fungsi terukur yang ekspresi X f dμ masuk akal dan, dalam arti yang samar, "rata-rata" dari f lebih X .

Diberikan ukuran pada set, seseorang dapat mendefinisikan "ukuran" untuk himpunan bagian dari set itu. Ini dilakukan dengan menetapkan subset integral dari fungsi karakteristiknya (dengan asumsi bahwa ini adalah fungsi yang dapat diukur). Ini bisa tak terbatas, atau tidak terdefinisi (keduanya agak berbeda).

Ada banyak langkah di sekitar, tetapi ada dua yang penting di sini. Salah satunya adalah ukuran standar pada garis nyata, ℝ. Untuk ukuran ini, maka f dμ cukup banyak apa yang Anda dapatkan di sekolah (apakah kalkulus masih diajarkan di sekolah?): Jumlahkan persegi kecil dan ambil lebar yang lebih kecil dan lebih kecil. Dalam ukuran ini, ukuran interval adalah lebarnya. Ukuran suatu titik adalah 0.

Ukuran penting lainnya, yang bekerja pada set apa pun , disebut ukuran titik . Ini didefinisikan agar integral suatu fungsi adalah jumlah dari nilainya:

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

Ukuran ini menetapkan untuk setiap singleton mengatur ukuran 1. Ini berarti bahwa subset memiliki ukuran terbatas jika dan hanya jika itu sendiri terbatas. Dan sangat sedikit fungsi memiliki integral yang terbatas. Jika suatu fungsi memiliki integral terbatas, itu harus bukan nol hanya pada jumlah poin yang dapat dihitung . Jadi sebagian besar fungsi yang mungkin Anda ketahui tidak memiliki integral hingga dalam ukuran ini.

Dan sekarang untuk fungsi delta. Mari kita ambil definisi yang sangat luas. Kami memiliki ruang terukur (X, μ) (jadi itu satu set dengan ukuran di atasnya) dan elemen sebuah ∈ X . Kami "mendefinisikan" fungsi delta (tergantung pada a ) menjadi "fungsi" δ a : X → ℝ dengan properti yang δ a (x) = 0 jika x ≠ a dan X δ a dμ = 1 .

Fakta paling penting tentang hal ini untuk ditahan adalah ini: Fungsi delta tidak harus berupa fungsi . Hal ini tidak benar didefinisikan: Saya belum mengatakan apa delta a (a) adalah.

Apa yang Anda lakukan pada titik ini tergantung pada siapa Anda. Dunia di sini terbagi menjadi dua kategori. Jika Anda seorang ahli matematika, Anda mengatakan yang berikut:

Oke, jadi fungsi delta mungkin tidak ditentukan. Penampilan Mari kita lihat sifat hipotetis dan melihat apakah kita dapat menemukan rumah yang tepat untuk itu di mana itu adalah didefinisikan. Kita bisa melakukan itu, dan kita berakhir dengan distribusi . Ini bukan fungsi (tentu saja), tetapi adalah hal-hal yang berperilaku sedikit seperti fungsi, dan seringkali kita dapat bekerja dengannya seolah-olah mereka adalah fungsi; tetapi ada hal-hal tertentu yang tidak mereka miliki (seperti "nilai") jadi kita perlu berhati-hati.

Jika Anda bukan ahli matematika, Anda mengatakan yang berikut:

Oke, jadi fungsi delta mungkin tidak didefinisikan dengan benar. Siapa bilang begitu? Sekelompok ahli matematika? Abaikan mereka! Apa yang mereka tahu

Setelah menyinggung hadirin saya, saya akan melanjutkan.

The Dirac delta biasanya diambil menjadi fungsi delta dari titik (sering 0) di garis nyata dengan ukuran standar. Jadi mereka yang mengeluh dalam komentar tentang saya tidak tahu delta saya melakukannya karena mereka menggunakan definisi ini. Bagi mereka, saya minta maaf: walaupun saya bisa keluar dari itu dengan menggunakan pertahanan Matematik (seperti yang dipopulerkan oleh Humpty Dumpty : cukup mendefinisikan kembali semuanya sehingga itu benar), itu adalah bentuk yang buruk untuk menggunakan istilah standar untuk mengartikan sesuatu yang berbeda.

Tapi ada adalah fungsi delta yang tidak melakukan apa yang saya ingin lakukan dan itu adalah bahwa yang saya butuhkan di sini. Jika saya mengambil ukuran titik pada set X kemudian ada adalah fungsi asli δ sebuah : X → ℝ yang memenuhi kriteria untuk fungsi delta. Ini karena kita mencari fungsi X → ℝ yang nol kecuali pada a dan sedemikian rupa sehingga jumlah semua nilainya adalah 1. Fungsi tersebut sederhana: satu-satunya informasi yang hilang adalah nilainya di a , dan untuk mendapatkan jumlah menjadi 1 kita hanya menetapkan nilai 1. Ini tidak lain adalah fungsi karakteristik pada {a} . Kemudian:

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

Jadi dalam hal ini, untuk himpunan tunggal, fungsi karakteristik dan fungsi delta setuju.

Kesimpulannya, ada tiga keluarga "fungsi" di sini:

  1. Fungsi karakteristik dari set singleton,
  2. Fungsi delta,
  3. Delta Kronecker berfungsi.

Yang kedua adalah yang paling umum karena yang lain adalah contoh ketika menggunakan ukuran titik. Tetapi yang pertama dan ketiga memiliki keuntungan bahwa fungsi mereka selalu asli. Yang ketiga sebenarnya adalah kasus khusus yang pertama, untuk keluarga domain tertentu (bilangan bulat, atau sebagian daripadanya).

Jadi, akhirnya, ketika saya awalnya menulis jawaban yang saya tidak berpikir benar (saya tidak akan pergi sejauh mengatakan bahwa saya bingung , karena saya berharap saya baru saja menunjukkan saya tidak tahu apa yang saya bicarakan ketika Saya sebenarnya berpikir dulu, saya hanya tidak berpikir banyak). Arti yang biasa dari dirac delta bukanlah yang diinginkan di sini, tetapi salah satu poin dari jawaban saya adalah bahwa domain input tidak didefinisikan sehingga delta Kronecker juga tidak akan benar. Dengan demikian jawaban matematis terbaik (yang saya tuju) adalah fungsi karakteristik .

Saya harap itu semua jelas; dan saya juga berharap bahwa saya tidak perlu menulis karya matematika lagi menggunakan entitas HTML daripada makro TeX!

Andrew Stacey
sumber
37
+1 - Jika saya bisa downvote Quentin karena tidak tahu fungsi dirac_delta saya akan. Saya ingin tahu perguruan tinggi mana yang dia tuju karena saya pikir saya tidak akan mempekerjakan orang dari sana jika mereka bahkan tidak tahu sesuatu yang mendasar bagi pemrosesan digital. Saya selanjutnya akan menurunkan suara Quentin karena ketidakmampuannya untuk memahami sedikit humor yang Anda coba.
Dunk
23
Jika saya menurunkan setiap jawaban yang saya tidak mengerti ... Saya akan menurunkan banyak jawaban.
Seamus
4
Halo Andrew, sudah lama.
Tim Down
4
@Tim: Ya ampun, sudah! Dan bagaimana dengan Uskup Bermuda? (Apakah saya ingat itu benar?) Saya kira utas komentar ini bukan tempat terbaik untuk mengejar ketinggalan, meskipun ... 17 tahun, bukan?
Andrew Stacey
3
@ Cԃ ա ԃ "Jawaban ini telah gagal ..." huh . Anda memang membaca bahwa saya seorang ahli matematika, bukan? Jawaban ini berfungsi sempurna untuk programmer bola dalam ruang hampa jadi saya tidak tahu apa yang Anda keluhkan.
Andrew Stacey
35

Anda bisa melakukannya

v = Math.abs(--v);

Penurunan menetapkan nilai ke 0 atau -1, dan kemudian Math.absmengkonversi -1 ke +1.

Paul
sumber
27
Ini telah berubah menjadi kompetisi 'Hasilkan 10000 cara untuk melakukan tugas sederhana'. Dan saya suka semua cara haha.
Josh
27
v = Math.round(Math.sin(Math.PI/(v+3)));
Benoit
15
@Benoit - rumus Anda sama dengan 1 untuk v = 0 dan v = 1. Yang ini benar! v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));: D
Teo.sk
2
Itu tidak akan pernah mengubah nilainya. Jika v = 1kemudian v = Math.Abs(-1)yang merupakan +1. Jika v = 0kemudian v = Math.Abs(-0)yang 0.
Paul
1
+1 Dan ini yang lain ... Grr.
Rekursif
34

secara umum setiap kali Anda perlu beralih antara dua nilai, Anda bisa mengurangi nilai saat ini dari jumlah dua nilai beralih:

    0,1 -> v = 1 - v
    1,2 -> v = 3 - v
    4,5 -> v = 9 - v 
Mouna Cheikhna
sumber
2
Ini menarik dan kreatif tetapi berpotensi berbahaya. Jika vmenjadi rusak itu akan tiba-tiba mulai beralih di antara dua nilai yang berbeda. (Hanya sesuatu yang perlu dipertimbangkan ...)
oosterwal
1
+1 untuk ide yang menarik. bukan bahwa OP atau orang lain benar-benar akan menggunakannya dalam keadaan ini, tetapi informasi ini harus ada di suatu tempat di otak selamanya.
Shimmy Weitzhandler
3
@ Oosterwal: Maka pasti masalahnya terletak pada korupsi ...
GManNickG
@GManNickG: Cepat atau lambat, korupsi data akan terjadi sehingga kita harus menyadari konsekuensi dari tidak mendeteksinya. Jika vbiasanya digunakan untuk mengeksekusi dua negara secara berurutan dari daftar tiga negara atau lebih, maka korupsi vdapat menyebabkan program mengeksekusi dua negara yang sama sekali berbeda - ini dapat menghasilkan hasil yang tidak terduga dan tidak diinginkan. Pelajaran yang bisa diambil dari ini adalah: Selalu lakukan pemeriksaan masuk akal pada data Anda.
oosterwal
33

Jika harus bilangan bulat 1 atau 0, maka cara Anda melakukannya baik-baik saja, meskipun tanda kurung tidak diperlukan. Jika ini akan digunakan sebagai boolean, maka Anda bisa melakukannya:

v = !v;
Michael Berkowski
sumber
10
bukankah ini akan menghasilkan "v" Ollie yang ditetapkan ke hasil boolean, bukan bilangan bulat?
Brian
12
Ya itu akan, dan saya memperingatkan bahwa dalam kalimat di atas baris kode. Jika ini harus digunakan sebagai boolean
Michael Berkowski
23
v = v == 0 ? 1 : 0;

Cukup !

nidhin
sumber
7
Lebih banyak pendapat daripada jawaban, bukan begitu?
Brian
16
@Brian: 'lebih baik' sebenarnya tentang opini.
pimvdb
3
Saya suka bagaimana Anda mengeluarkan braket - yang memangkas beberapa karakter!
Ollie Glass
9
@Brian: " Jawaban " adalah "Tidak, tidak ada cara menulis yang lebih baik v = (v==0 ? 1 : 0);" . Semua orang menemukan cara bermain golf yang berbeda; dan tidak benar-benar menjawab pertanyaan itu. Itu sebabnya saya memilih jawaban ini.
Ian Boyd
19

Daftar solusi

Ada tiga solusi yang ingin saya usulkan. Semua dari mereka mengkonversi nilai apapun untuk 0(jika 1, truedll) atau 1(jika 0, false, nulldll):

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

dan satu tambahan, telah disebutkan, tetapi pintar dan cepat (meskipun hanya berfungsi untuk 0s dan 1s):

  • v = 1-v

Solusi 1

Anda dapat menggunakan solusi berikut:

v = 1*!v

Ini pertama akan mengkonversi bilangan bulat ke boolean berlawanan ( 0ke Truedan nilai lain untuk False), maka akan memperlakukannya sebagai bilangan bulat ketika mengalikannya dengan 1. Akibatnya 0akan dikonversi ke 1dan nilai lainnya ke 0.

Sebagai bukti lihat jsfiddle ini dan berikan nilai apa saja yang ingin Anda uji: jsfiddle.net/rH3g5/

Hasilnya adalah sebagai berikut:

  • -123akan dikonversi ke integer 0,
  • -10akan dikonversi ke integer 0,
  • -1akan dikonversi ke integer 0,
  • 0akan dikonversi ke integer 1,
  • 1akan dikonversi ke integer 0,
  • 2akan dikonversi ke integer 0,
  • 60akan dikonversi ke integer 0,

Solusi 2

Seperti yang dicatat mblase75, jAndy memiliki beberapa solusi lain yang berfungsi sebagai milik saya:

v = +!v

Itu juga pertama membuat boolean dari nilai asli, tetapi menggunakan +alih-alih 1*mengubahnya menjadi integer. Hasilnya persis sama, tetapi notasi lebih pendek.

Solusi 3

Pendekatan lain adalah menggunakan ~~operator:

v = ~~!v

Ini sangat jarang dan selalu mengkonversi ke integer dari boolean.

Tadeck
sumber
Dalam JavaScript, Anda dapat mengawali variabel dengan +mengonversinya menjadi angka, jadi +!vsama dengan solusi Anda (solusi jAndy dalam komentar OP).
Blazemonger
@ mblase75: Ya, Anda benar yang 1*bisa diganti +ketika mencoba mengubah boolean menjadi integer. Semua yang lain dalam jawaban saya tetap sama. Jawaban jAndy benar, tetapi jawaban saya lebih detail. Saya akan menambahkan solusinya pada jawaban saya.
Tadeck
@Tadeck +1 untuk ide yang bagus.
Shimmy Weitzhandler
17

Untuk meringkas jawaban lain, komentar dan pendapat saya sendiri, saya sarankan menggabungkan dua hal:

  1. Gunakan fungsi untuk beralih
  2. Di dalam fungsi ini menggunakan implementasi yang lebih mudah dibaca

Berikut adalah fungsi yang bisa Anda tempatkan di perpustakaan atau mungkin membungkusnya dalam Plugin untuk Javascript Framework lainnya.

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

Dan penggunaannya sederhana:

v = inv(v);

Keuntungannya adalah:

  1. Tidak Ada Duplikasi kode
  2. Jika Anda atau siapa pun membaca ini lagi di masa mendatang, Anda akan memahami kode Anda dalam waktu minimum.
Martin Schlagnitweit
sumber
Apakah mereka? Saya menjalankan tes cepat: jsperf.com/function-vs-no-function/2 dan tampaknya, perbedaannya tidak terlalu banyak.
Martin Schlagnitweit
25
7.5ns vs 8.8ns. Tambahan 1,3 nanodetik akan benar-benar membunuhmu.
Ian Boyd
5
Dengan semua waktu yang saya tabung, saya membawa keluarga saya ke Disney World! :-)
Tom
1
Benar sekali. Orang yang menulis solusi "pintar" mungkin tidak pernah harus mempertahankan kode "permata" programmer lainnya
Avi
1
mengapa tidak function toggle(i){ return i == 0 ? 1 : 0 }?
Billy Moon
13

Saya tidak tahu mengapa Anda ingin membangun boolean Anda sendiri? Saya suka sintaks yang funky, tapi mengapa tidak menulis kode yang bisa dimengerti?

Ini bukan yang terpendek / tercepat, tetapi yang paling jelas (dan dapat dibaca untuk semua orang) menggunakan status if / else yang terkenal:

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

Jika Anda ingin benar-benar jelas, Anda harus menggunakan boolean alih-alih angka untuk ini. Mereka cukup cepat untuk kebanyakan kasus. Dengan booleans, Anda bisa menggunakan sintaks ini, yang akan menang dalam waktu singkat:

v = !v;
Mark Knol
sumber
1
Ini sebenarnya akan menjadi jawaban pilihan saya; tetapi operator ternary vs jika-lain adalah perang suci saya tidak ingin menyalakan sekering. Yang mengatakan, saya pikir seharusnya baris pertama === 0. Dengan input sampel 7, output yang benar adalah 0, tetapi ini akan menampilkan 1.
Ian Boyd
4
Apakah ada nilai untuk mengoreksi input seperti 7 daripada diam-diam melemparkan pengecualian? Maksud saya, bagaimana jika ada sedikit kode lain yang dapat diperoleh dari angka 7 ketika mengharapkan 0 atau 1 saja, sebelum kode Anda mengoreksi nilainya?
Chuck van der Linden
12

Bentuk lain dari solusi asli Anda:

v = Number(v == 0);

EDIT: Terima kasih TehShrike dan Guffa untuk menunjukkan kesalahan dalam solusi asli saya.

Kurt Kaylor
sumber
4
Operator == mengembalikan boolean (bukan bilangan bulat) di bawah banyak sistem. Ini hanya akan berfungsi jika v didefinisikan sebagai integer, dan bahasanya keren dengan casting otomatis dari boolean ke integer.
TehShrike
Sangat benar. Saya menjawab pertanyaan dalam konteks javascript (bagaimana pertanyaan itu ditandai).
Kurt Kaylor
@Kurt Kaylor: Javascript adalah salah satu sistem di mana operator == mengembalikan boolean, jadi itu tidak melakukan hal yang sama dengan solusi asli.
Guffa
@Guffa: Saya mengambil keuntungan dari fakta bahwa javascript adalah bahasa yang diketik dengan lemah dengan konversi tipe implisit (eg'0.0000 '== 0, 0 == "", false == "", false == 0, 1 == benar, dll). Saya dapat menggunakan nilai boolean yang dikembalikan dengan cara yang sama seperti saya dapat menggunakan bilangan bulat dari nilai 0 atau 1. Coba, misalnya, untuk mengevaluasi "2 + true" di konsol javascript, Anda akan mendapatkan 3.
Kurt Kaylor
1
@Kurt Kaylor: Itu hanya berfungsi dalam situasi di mana Anda memaksakan konversi implisit. Coba misalnya 'opacity:'+truedan Anda berakhir dengan opacity:truealih - alih opacity:1.
Guffa
11

Saya akan membuatnya lebih eksplisit.

Apa vartinya

Sebagai contoh ketika v adalah suatu keadaan. Buat Status objek. Dalam DDD objek nilai.

Terapkan logika dalam objek nilai ini. Kemudian Anda dapat menulis kode Anda dengan cara yang lebih fungsional yang lebih mudah dibaca. Pergantian status dapat dilakukan dengan membuat Status baru berdasarkan status saat ini. Pernyataan / logika if Anda kemudian dienkapsulasi dalam objek Anda, yang dapat Anda pisahkan. ValueObject selalu berubah, sehingga tidak memiliki identitas. Jadi untuk mengubah nilainya, Anda harus membuat yang baru.

Contoh:

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);
Marco
sumber
6
lebih dari rekayasa?
alejandro5042
6
+1 untuk membuat saya tertawa
Denshi
10

Cara lain untuk melakukannya:

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

Ini tidak ada:

v = [1, 0][v];

Ini berfungsi sebagai round robin juga:

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

Atau

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

Pesona solusi terakhir, ia bekerja dengan semua nilai lain juga.

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

Untuk kasus yang sangat khusus, ingin mendapatkan nilai (perubahan) dan undefined, pola ini mungkin membantu:

v = { undefined: someValue }[v]; // undefined someValue undefined someValue undefined ...
Nina Scholz
sumber
9

Karena ini adalah JavaScript, kita dapat menggunakan unary +untuk mengonversi ke int:

v = +!v;

Ini akan logis NOTnilai v(memberi truejika v == 0atau falsejika v == 1). Kemudian kami mengubah nilai boolean yang dikembalikan ke representasi integer yang sesuai.

0x499602D2
sumber
8

Hanya untuk iseng: v = Math.pow(v-1,v)matikan juga antara 1 dan 0.

Blazemonger
sumber
7

Satu lagi: v=++v%2

(dalam C itu akan sederhana ++v%=2)

ps. Ya, saya tahu ini penugasan ganda, tetapi ini hanya penulisan ulang mentah metode C (yang tidak berfungsi sebagaimana mestinya, menyebabkan operator pra-kenaikan JS tidak mengembalikan nilai l.

Adam Jurczyk
sumber
3
Versi C Anda ilegal; Anda tidak dapat mengubah hasil dari ++operator (ini bukan nilai tambah). Adapun v=++v%2, Anda memodifikasi vdua kali. Saya tidak tahu apakah itu didefinisikan dengan baik dalam JavaScript, tetapi itu tidak perlu. v = (v+1) % 2.
Keith Thompson
Setidaknya di c++dalamnya adalah - karena operator pra-kenaikan memiliki prioritas lebih tinggi dan memodifikasi variabel 'di tempat', sehingga dapat digunakan sebagai nilai. Saya berpikir bahwa implementasi JS ++adalah sedemikian rupa sehingga tidak dapat diperlakukan sebagai lvalue: / Dan ya, ini berlebihan, tetapi saya mencoba menunjukkan metode lain - sudah ada solusi yang diposting lebih baik :)
Adam Jurczyk
3
+1. Dapat ditulis sebagai v = (v + 1)% 2.
niktrs
7

Jika Anda dijamin input Anda adalah 1 atau 0, maka Anda dapat menggunakan:

v = 2+~v;
brandx
sumber
7

tentukan array {1,0}, atur v ke v [v], oleh karena itu v dengan nilai 0 menjadi 1, dan vica sebaliknya.

S ..
sumber
Solusi saya benar, jika Anda tidak suka, tuliskan alasannya. Komentar Anda tidak membantu siapa pun. Solusi saya membaca variabel, bukan membuat keputusan. Ini membutuhkan lebih sedikit CPU.
S ..
5

Cara kreatif lain untuk melakukannya, dengan vsetara dengan nilai apa pun, akan selalu kembali 0atau1

v = !!v^1;
Yanick Rochon
sumber
3
dua !!menghasilkan apa-apa dalam matematika logis, Anda dapat dimasukkan !!!!ke sana dan akan sama tetapi menghasilkan 4 operasi yang tidak diperlukan
Alex K
10
@ Alex: !!akan dilemparkan ke bool. !!(1) === truedan!!(0) === false
nickf
1
@nickf: aha, jadi saya kira v = Boolean(v^1)akan lebih informatif, terima kasih untuk menjelaskan - tidak berpikir tentang casting
Alex K
1
@ Alex, "matematika logis"? Inilah sebabnya mengapa matematikawan adalah programmer yang buruk. Jangan salah sangka; programmer yang baik juga pandai memahami matematika. Tapi ini tidak ada hubungannya dengan matematika logis. Ini adalah konstruksi bahasa yang, dengan ekspresi apa pun, setidaknya dalam Javascript, !akan mengubahnya menjadi boolean. Menambahkan yang lain !akan meniadakan boolean itu. Castingnya implisit di sini, dan hasil akhirnya bekerja. Tidak perlu untuk -1.
Yanick Rochon
1
Saya bukan ahli matematika sama sekali. Anda dapat mencoba ini dan lihat sendiri jsperf.com/javascript-boolean-test
Alex K
4

Jika nilai yang mungkin untuk v hanya 0 dan 1, maka untuk sembarang bilangan bulat x, ekspresi: v = Math.pow ((Math.pow (x, v) - x), v); akan beralih nilainya.

Saya tahu ini adalah solusi yang jelek dan OP tidak mencari ini ... tapi saya hanya memikirkan solusi lain ketika saya di toilet: P

Amit
sumber
3
v=!v;

akan bekerja untuk v = 0 dan v = 1; dan beralih negara;

guru
sumber
1

Jika hanya ada dua nilai, seperti dalam hal ini (0, 1), saya percaya itu boros untuk menggunakan int. Lebih baik pergi untuk boolean dan bekerja dalam bit. Saya tahu saya berasumsi tetapi dalam kasus beralih antara dua negara, boolean tampaknya menjadi pilihan ideal.

Amber
sumber
1

Nah, Seperti yang kita ketahui bahwa dalam javascript hanya itu perbandingan Boolean juga akan memberi Anda hasil yang diharapkan.

yaitu v = v == 0cukup untuk itu.

Di bawah ini adalah kode untuk itu:

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/

Berharap ini akan membantu Anda :)

Vikash Pandey
sumber
Itu berfungsi untuk beralih nilai, tetapi nilai tidak beralih antara 0 dan 1, tetapi antara truedan false. Anda dapat menggunakan v == 0untuk menentukan nilai variabel dalam suatu kondisi, tetapi jika Anda ingin menggunakan nilai 0 atau 1 Anda harus menggunakan sesuatu seperti v == 0 ? 0 : 1atau Number(v)untuk mendapatkan itu. (Juga, Anda dapat menggunakan v = !v;untuk beralih antara truedan false.)
Guffa
ya mengerti .. terima kasih :)
Vikash Pandey
0

v = Nomor (! v)

Ini akan mengetikkan melemparkan nilai Boolean Terbalik ke Angka, yang merupakan output yang diinginkan.

Rohit Goyal
sumber