Чи є кращий спосіб написання v = (v == 0? 1: 0); [зачинено]


465

Я хочу переключити змінну між 0 і 1. Якщо це 0, я хочу встановити її на 1, інакше, якщо це 1, я хочу встановити її на 0.

Це така фундаментальна операція, про яку я пишу так часто, я хотів би дослідити найкоротший, найясніший можливий спосіб її виконання. Ось мій найкращий поки що:

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

Чи можете ви покращити це?

Редагувати: питання полягає в тому, як записати вищезазначене твердження в найменші символи, зберігаючи ясність - як це "не справжнє запитання"? Це не передбачалося вправою з кодовим гольфом, хоча люди отримали кілька цікавих відповідей як гольф - приємно бачити, як гольф використовується як конструктивний та продуманий спосіб.


20
Для мене це виглядає вже просто / ясно / коротко.
Моб

136
хитрість:v = +!v;
jAndy

48
Якщо "краще" означає "швидше": jsperf.com/v-0-1-0 .
pimvdb

7
@Mobinga: +1. Це так просто, як і слід. Усі інші відповіді, які я бачу, є заплутаними, а деякі з них змінюють логіку; введення помилок.
Ян Бойд

8
@holodoc Кращим рішенням для висловлення своєї думки було б створити відповідь, яка каже, що ви вважаєте, що оригінал - це найкращий спосіб, і детально пояснити, ЧОМУ ви вважаєте, що це так. що також дозволяє іншим людям легко зіткнутися з вашою відповіддю, проголосувавши її.
Чак ван дер Лінден

Відповіді:


721

Ви можете просто використовувати:

v = 1 - v;

Звичайно, це передбачає, що змінна ініціалізується належним чином, тобто вона має лише значення 0 або 1.

Ще один метод, який коротший, але використовує менш поширений оператор:

v ^= 1;

Редагувати:

Бути зрозумілим; Я ніколи не підходив до цього питання як кодового гольфу, просто щоб знайти короткий спосіб виконання завдання, не використовуючи жодних прихованих хитрощів, як побічні ефекти операторів.


206
Це красиві рядки коду, як дрібно нарізане скло або рідкісні квітучі орхідеї. Мені подобається, як ти пройшов прямо через логічний рівень і мав справу безпосередньо з математикою 1 і 0 з найбільш оптимальними можливими операціями. Я буду використовувати їх у своїх власних проектах, але, на жаль, коли мені потрібен код, щоб його зрозуміли колеги, мені доведеться за замовчуванням застосовувати більш логічний підхід. Дякую, хоча ваша відповідь зробила мій день.
Оллі Гласс

37
Ви завжди можете додати коментар, сказавши, що робить код.
Пруссе

25
@Kevin: Неправда, що це однозначно не відповідає на запитання. Q сказав: "Я хочу переключити змінну між 0 і 1." Дуже розумне тлумачення полягає в тому, що це означає, що значення змінної вже або 0, або 1. Ця інтерпретація / обмеження було зроблено у відповіді явним. Що у світі можна заперечити?
LarsH

50
@Matthew сказати, що той, хто не знаходить v ^= 1ясного, повинен припинити програмування, я думаю, що це трохи суворо. Як раніше було заявлено, він не є одним з найбільш поширених операторів, і він не робить те саме, що v = v ^ 1. Також оператор означає щось зовсім інше на різних мовах (VB). Так, швидкий пошук скаже вам, що його оператор XOR, і ви зрозумієте, що він робить, але для багатьох це може бути не очевидно на перший погляд. Я не думаю, що це означає, що вам потрібно кинути роботу.
JD Isaacks

80
Якщо ви збережете 15 символів, написавши це, але потім використайте 40 символів коментарів, щоб пояснити це, чи справді це поліпшення?
Майкл Майерс

343

Так 0як це falseзначення і 1є trueцінністю.

v = (v ? 0 : 1);

Якщо ви раді використовувати trueі falseзамість цифр

v = !v;

або якщо вони повинні бути числами:

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

55
просто поставте +перед цим магію !. О, це виглядає так брудно! але круто: p
jAndy

1
@Quentin - це порушить код хлопця, якщо він має, switch(v){ case 0 ...або якщо (v == 0) або якщо v === 0. Ви змінюєте його результат на додаток до свого підходу ....
Брайан

34
Зробити смайлик з нього: ({v :+! v}).v.
pimvdb

17
@Brian: не з цим чарівним +знаком! ¯ \ _ (ツ) _ / ¯
jAndy

11
+1 для v = (v ? 0 : 1)як чіткого та ідіоматичного JS.
Bennett McElwee

200

v = (v + 1) % 2і якщо вам потрібно переглянути більше значень, просто змініть 2на (n + 1). Скажіть, що вам потрібно зробити цикл 0,1,2 просто v = (v + 1) % 3.


2
Я люблю цикл! Це справді розумно.
Оллі Гласс

16
+1 для роздумів про перемикання як про цикл. Простий, враховуючи, наскільки він гнучкий.
Guffa

3
+1 для надання модульного рішення, яке також є надійним. На практиці ви, напевно, хочете використовувати constзмінну замість магічних чисел 2, 3, ...
oosterwal

2
Коротший (хакірший) спосіб: ++v % 3якщо ви хочете проїхати через 0, 1, 2
haraldmartin

75

Ви можете написати функцію для неї та використовувати її так:

v = inv(v)


30
+1 Я повністю погоджуюся, що це найчистіше рішення (... але тоді, що йде у invфункції: P)
Lea Hayes

4
Я б хотів, щоб я міг дати цю відповідь більше, ніж просто +1. Якщо загальний код не є наочно очевидним, його слід загорнути у функцію з описовою назвою.
TehShrike

11
@TehShrike чи вважаєте ви invописовою назвою?
Bennett McElwee

3
@Bennett McElwee: inv = інвертувати. Завжди здавалося мені загальним абревіатурою.
Даніель

51
Навіщо скорочувати його тоді, називайте його "інвертувати" або "тумблер" і код має читати. це не так, якби ми намагаємось помістити цей матеріал на перфокартку з 80 стовпчиками чи щось таке.
Чак ван дер Лінден

50

Якщо вас не хвилює будь-яка можливість, окрім 1:

v = v ? 0 : 1;

У вищенаведеному випадку v в кінцевому підсумку буде 1, якщо v дорівнює 0, помилковим, невизначеним або нульовим. Будьте обережні, використовуючи такий підхід - v буде 0, навіть якщо v "привіт світ".


2
Це не переверне значення. Ви маєте на увазі v = v ? 0 : 1.
Guffa

3
@Guffa - +1 для лову на мою дислексію ...
Брайан

3
Це моя улюблена відповідь на основі логіки, яку я можу використовувати разом із колегами (я бачу відповідь @ Гуффи як число). Мені подобається, як ви взяли непотрібний тест (v == 0) і дужки, знімаючи його до абсолютного мінімального числа символів. Дякую.
Оллі Гласс

1
Я також великий прихильник відповіді @ Гуффи - словами Лінард Скайнард, будьте простою людиною;)
Брайан

2
+1 для розуміння "правдоподібних" цінностей.
zzzzBov

44

Рядки на кшталт v = 1 - v, або v ^= 1або v= +!vвсі зроблять роботу, але вони складають те, що я б назвав хакі. Це не красиві рядки коду, а дешеві хитрощі, щоб мати намічений ефект. 1 - vне повідомляє "перемикає значення між 0 і 1". Це робить ваш код менш виразним і вводить місце (хоч і невелике), де інший розробник повинен буде проаналізувати ваш код.

Натомість функція, подібна до того, v = toggle(v)передає наміри якнайшвидшого погляду.


8
-1, серйозно, v=1-vне передає тумблер?
Сліпий

22
1-vможе спілкуватися дійсно перемикатися, але це єдине, що він спілкується. Наприклад, він також може передавати лінію з нулем у v=1або дзеркальне перетворення, зосереджене в v=0.5. У цьому сенсі це досить неоднозначно. Це правда, що знаючи, що це vможе бути коли-небудь 0або 1обмежує його передбачуване значення, але це змушує інших розробників (або вашого майбутнього ") розуміти цей контекст, перш ніж мати можливість зрозуміти цю просту лінію. Ви не можете бути набагато зрозумілішим, ніжv = toggle(v)
Рей

10
v ^= 1Цілком зрозуміло, якщо ви розумієте логічні операції, хоча вам було б краще, якщо ви програміст. Я думаю, що це різниця між тим і v=1-v; це логічна операція, а арифметична - ми намагаємось представляти логічне поняття, а не математичне.
Матвій

6
@Matthew Read: Це чудове твердження, яке добре резюмує мої думки: "ми намагаємось представляти логічне поняття, а не математичне". Хоча навіть v ^= 1є деяка неоднозначність, як це можна трактувати як побіт-xor.
Рей

6
для програмістів (і так, я маю на увазі вун, як ми), ці цілком зрозумілі. Вони не хакі, адже це елегантні рішення завдяки їхній простоті.
gion_13

38

( Чесність і математична цілісність - враховуючи кількість голосів за цю "відповідь" - змусили мене відредагувати цю відповідь. Я відмовився якомога довше, тому що він був призначений як короткий запит, а не як "глибокий", тому введення будь-яке пояснення здавалося протилежним меті. Однак у коментарях чітко видно, що я повинен бути зрозумілим, щоб уникнути непорозуміння. )

Моя оригінальна відповідь:

Формулювання цієї частини специфікації:

Якщо це 0, я хочу встановити його на 1, а інше - на 0.

випливає, що найбільш точне рішення:

v = dirac_delta(0,v)

По- перше, визнання: я зробив , щоб мої дельта - функції сплутати. Дельта Kronecker була б трохи доречнішою, але не настільки, як я хотів чогось, що не залежить від домену (дельта Kronecker використовується в основному лише для цілих чисел). Але я дійсно не повинен був використовувати функції дельти взагалі, я повинен був сказати:

v = characteristic_function({0},v)

Дозвольте уточнити. Нагадаємо , що функція є потрійний, (X, Y, F) , де Х і Y представляють собою набори ( так званий домен і кообласть відповідно) і е є правило , яке присвоює елемент Y до кожного елементу X . Ми часто пишемо потрійний (X, Y, F) , як F: X → Y . Враховуючи підмножину X , скажімо, A , є характерна функція, яка є функцією χ A : X → {0,1}(це також може розглядатися як функція для більшого кодомену, такого як ℕ або ℝ). Ця функція визначена правилом:

χ (х) = 1 , якщо х ∈ A і χ (х) = 0 , якщо х ∉ .

Якщо вам подобаються таблиці істинності, це таблиця істинності для питання "Чи елемент x з X є елементом підмножини A ?".

Отже, з цього визначення зрозуміло, що характерна функція - це те, що тут потрібно, причому X має великий набір, що містить 0 і A = {0} . Це я мав би написати.

І так до дельта-функцій. Для цього нам потрібно знати про інтеграцію. Або ти вже знаєш це, або не знаєш. Якщо ви цього не зробите, я тут нічого не можу сказати про тонкощі теорії, але я можу дати коротке резюме. Міра на безлічі X , по суті , «то , що потрібно , щоб зробити роботу усредняет». Тобто сказати , що якщо у нас є безліч X і міра М на цій множині , тобто клас функцій X → ℝ , називається вимірні функціями , для яких вираз X е де має сенс і, в якому - то смутний почутті, «середнє» з F над X .

Враховуючи міру на множині, можна визначити "міру" для підмножини цього набору. Це робиться шляхом присвоєння підмножині інтегралу його характерної функції (припустимо, що це вимірювана функція). Це може бути нескінченно або невизначено (обидва вони тонко різні).

Навколо існує маса заходів, але тут важливі дві. Один - це стандартна міра на дійсній лінії, ℝ Для цього заходу, то е ДЙ є в значній мірі те , що ви отримуєте в школі вчили (це обчислення вчив ще в школі?): Підсумувати маленькі прямокутники і прийняти все менше і менше ширину. У цьому вимірі мірою інтервалу є його ширина. Міра точки дорівнює 0.

Ще одна важлива міра, яка працює на будь-якій множині, називається точковою мірою . Він визначається так, що інтеграл функції - це сума її значень:

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

Цей захід призначає кожному однотонному набору міру 1. Це означає, що підмножина має кінцеву міру тоді і лише тоді, коли вона сама є кінцевою. І дуже мало функцій мають кінцевий інтеграл. Якщо функція має кінцевий інтеграл, вона повинна бути не нульовою лише на підрахунковій кількості точок. Таким чином, переважна більшість функцій, які ви, напевно, знаєте, не мають кінцевого інтеграла під цим заходом.

А тепер до дельта-функцій. Візьмемо дуже широке визначення. У нас є вимірне простір (X, μ) (так що це безліч з заходом на ньому) і елемент ∈ X . Ми "визначимо" дельта-функцію (залежно від а ) бути "функцією" δ a : X → ℝ з властивістю, що δ a (x) = 0, якщо x ≠ a і X δ a dμ = 1 .

Найважливіший факт щодо цього, щоб зафіксувати це: Дельта-функція не повинна бути функцією . Це НЕ правильно визначено: Я не сказав , що & delta (а) є.

Що ви робите в цей момент, залежить від того, хто ви є. Світ тут ділиться на дві категорії. Якщо ви математик, ви говорите наступне:

Гаразд, тому дельта-функція може бути не визначена. Давайте подивимося на його гіпотетичних властивостей і подивитися , якщо ми зможемо знайти правильний будинок для неї , де вона буде визначена. Ми можемо це зробити, і закінчимо розповсюдження . Це не (обов'язково) функції, але це речі, які поводяться трохи як функції, і часто ми можемо працювати з ними так, ніби вони були функціями; але є певні речі, яких у них немає (наприклад, "значення"), тому нам потрібно бути обережними.

Якщо ви не математик, ви говорите наступне:

Гаразд, тому дельта-функція може бути неправильно визначена. Хто так каже? Купка математиків? Ігноруйте їх! Що вони знають?

Тепер образив мою аудиторію, я продовжуватиму.

Діраковской дельта зазвичай береться дельта - функція точки (часто 0) в реальному відповідності зі своєю стандартною мірою. Тож ті, хто скаржиться в коментарях про мене, не знаючи моїх дельтів, роблять це, тому що вони використовують це визначення. За них я вибачаюся: хоча я можу вийти з цього, використовуючи захист математика (як популяризує Humpty Dumpty : просто переосмислити все так, щоб це було правильно), погана форма використовувати стандартний термін, щоб означати щось інше.

Але є дельта-функція, яка робить те, що я хочу, і це те, що мені тут потрібно. Якщо взяти міру точки на безліч X , тобто є справжньою функція δ в : X → ℝ , яка задовольняє критерії для дельта - функції. Це тому, що ми шукаємо функцію X → ℝ, яка дорівнює нулю, за винятком а, та така, що сума всіх її значень дорівнює 1. Така функція проста: єдиний пропущений фрагмент інформації - це її значення в , а щоб отримати суму дорівнює 1, ми просто присвоїмо їй значення 1. Це не що інше, як характерна функція на {a} . Тоді:

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

Тож у цьому випадку для одинарного набору характерна функція та дельта-функція узгоджуються.

На закінчення, тут є три родини "функцій":

  1. Характерні функції однотонних множин,
  2. Дельта функцій,
  3. Функціонує дельта Kronecker.

Другий з них є найбільш загальним , як будь-який з інших є прикладом цього при використанні вимірювання точки. Але перші та треті мають перевагу в тому, що вони завжди є справжніми функціями. Третій насправді є особливим випадком першого, для певного сімейства доменів (цілих чисел або їх підмножини).

Отже, нарешті, коли я спочатку написав відповідь, я не міркував належним чином (я б не пішов так далеко, щоб сказати, що я був розгублений , тому що я сподіваюся, що щойно продемонстрував, що знаю, про що говорю, коли Я насправді думаю по-перше, я просто не дуже думав). Звичайний сенс дельти dirac - це не те, що тут потрібно шукати, але одним із пунктів моєї відповіді було те, що вхідний домен не був визначений, тому дельта Kronecker також не була б правильною. Таким чином, найкращою математичною відповіддю (на яку я мав на меті) була б характерна функція.

Я сподіваюся, що це все зрозуміло; і я також сподіваюся, що мені ніколи більше не доведеться писати математичний фрагмент, використовуючи HTML-об'єкти замість TeX-макросів!


37
+1 - Якби я міг спростувати Квентіна за те, що він не знав функції dirac_delta, я би. Я хотів би знати, в який коледж він пішов, тому що я не думаю, що я б наймав когось звідти, якщо вони навіть не знають чогось принципового для цифрової обробки. Я б хотів подати заяву Квентіну за його нездатність зрозуміти шматочок гумору, який ви намагалися.
Данк

23
Якби я відповідав за будь-яку відповідь, яку я не розумів ... я би спростував багато відповідей.
Seamus

4
Привіт, Ендрю, минув час.
Тім Даун

4
@Tim: Добре горе, так воно і є! А як єпископ Бермудський? (Я пам’ятав це правильно?) Я думаю, що ця тема коментарів - не найкраще місце, де можна наздогнати, хоча ... 17 років, чи не так?
Ендрю Стейсі

3
@ Cԃ ա ԃ "Ця відповідь не вдалася ..." зітхніть . Ви читали, що я математик, чи не так? Ця відповідь ідеально підходить для сферичного програміста у вакуумі, тому я не знаю, на що ви скаржитеся.
Ендрю Стейсі

35

Ви могли б зробити

v = Math.abs(--v);

Декремент встановлює значення 0 або -1, а потім Math.absперетворює -1 в +1.


27
Це перетворилося на змагання "Створіть 10000 способів зробити просту задачу". І мені подобаються всі способи ха-ха.
Джош

27
v = Math.round(Math.sin(Math.PI/(v+3)));
Бенуа

15
@Benoit - ваша формула дорівнює 1 для v = 0 і v = 1. ЦЬОГО є правильним, хоча! v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));: D
Teo.sk

2
Це ніколи не змінить значення. Якщо v = 1тоді, v = Math.Abs(-1)що є +1. Якщо v = 0тоді, v = Math.Abs(-0)що дорівнює 0.
Павло

1
+1 І це був мій інший ... Гр.
рекурсивна

34

загалом, коли вам потрібно перемикатися між двома значеннями, ви можете просто відняти поточне значення від суми двох значень перемикання:

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

2
Це цікаво та творчо, але потенційно небезпечно. Якщо vвін зіпсується, він раптом почне перемикатися між двома різними значеннями. (Просто щось врахувати ...)
oosterwal

1
+1 за цікаву ідею. не те, що ОП чи хтось інший насправді збирається використовувати його в цих умовах, але ця інформація повинна існувати десь у мозку назавжди.
Шиммі Вайцхандлер

3
@oosterwal: Тоді, безумовно, проблема полягає в корупції ...
GManNickG

@GManNickG: Рано чи пізно відбудеться пошкодження даних, тому нам потрібно знати про наслідок того, щоб його не виявити. Якщо vзазвичай використовується по черзі виконання двох станів зі списку трьох або більше станів, корупція vможе призвести до того, що програма може по черзі виконувати два абсолютно різні стани - це може призвести до несподіваних і небажаних результатів. Урок, який потрібно позбавити від цього, полягає у тому, щоб: Завжди виконувати перевірки правдоподібності своїх даних.
oosterwal

33

Якщо це повинно бути ціле число 1 або 0, то спосіб, який ви робите, добре, хоча дужки не потрібні. Якщо ці a використовуватимуться як булеві, то ви можете просто зробити:

v = !v;

10
чи не призведе цей результат в тому, що "v" Оллі буде встановлено як бульовий результат, а не ціле число?
Брайан

12
Так, це буде, і я попередив це у реченні над рядком коду. Якщо ці підлягають використанню як булеви
Michael Berkowski

23
v = v == 0 ? 1 : 0;

Достатньо !


7
Більше думки, ніж відповіді, ти не вважаєш?
Брайан

16
@Brian: "краще" насправді все стосується думки.
pimvdb

3
Мені подобається, як ти зняв дужки - це обрізає пару символів!
Оллі Гласс

9
@Brian: " Відповідь " - "Ні, немає кращого способу написання v = (v==0 ? 1 : 0);" . Всі інші знаходять різні способи гри в гольф; і фактично не відповідаючи на питання. Тому я відповів голосом за цю відповідь.
Ян Бойд

19

Список рішень

Я б хотів запропонувати три рішення. Усі вони перетворюють будь-яке значення в 0(якщо 1і trueт.д.) або 1(якщо 0, falseі nullт.д.):

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

і один додатковий, уже згаданий, але розумний і швидкий (хоча працює лише для 0s і 1s):

  • 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

Це досить рідко і завжди перетворюється на ціле число з булевого.


В JavaScript ви можете встановити префікс змінної, +щоб перетворити її в число, тому +!vеквівалентний вашому рішенню (рішення jAndy в коментарях ОП).
Blazemonger

@ mblase75: Так, ви праві, що 1*їх можна замінити, +намагаючись перетворити булеве значення в ціле число. Все інше у моїй відповіді залишається тим самим. Відповідь jAndy правильна, але моя більш детальна. Я додам його / її рішення до своєї відповіді.
Тадек

@Tadeck +1 за гарну ідею.
Шиммі Вайцхандлер

17

Підсумовуючи ще одну відповідь, коментар та власну думку, я пропоную поєднати дві речі:

  1. Використовуйте функцію для перемикання
  2. Всередині цієї функції використовуйте більш читану реалізацію

Ось функція, яку ви можете розмістити в бібліотеці або, можливо, обернути її у плагін для іншого Javascript Framework.

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

А використання просто:

v = inv(v);

Перевагами є:

  1. Без копіювання коду
  2. Якщо ви чи хтось читатиме це ще раз у майбутньому, ви зрозумієте свій код за мінімальний час.

Чи вони? Я пройшов швидкий тест: jsperf.com/function-vs-no-function/2, і, здається, різниця не така вже й велика.
Martin Schlagnitweit

25
7,5с проти 8,8с. Ці додаткові 1,3 наносекунди справді вб'ють вас.
Ян Бойд

5
За весь час заощадження я відвіз свою родину у світ Діснея! :-)
Том

1
Цілком правильно. Люди, які пишуть "розумні" рішення, ймовірно, ніколи не мали підтримувати код інших програмістів "дорогоцінні камені"
Avi

1
чому ні function toggle(i){ return i == 0 ? 1 : 0 }?
Біллі Мун

13

Я не знаю, чому ви хочете створити власні булеви? Мені подобаються прикольні синтаксиси, але чому б не написати зрозумілий код?

Це не найкоротший / найшвидший, але найбільш зрозумілий (і читабельний для всіх) - це використання відомого стану if / else:

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

Якщо ви хочете бути по-справжньому зрозумілими, для цього слід використовувати булі, а не цифри. Вони досить швидкі для більшості випадків. З булевими, ви можете просто використовувати цей синтаксис, який виграє в стислість:

v = !v;

1
Це насправді моя найкраща відповідь; але потрійний оператор проти інше - це свята війна, я не хотів запалювати запобіжник. Однак, я думаю, що перший рядок повинен бути === 0. При введенні зразка 7правильний вихід є 0, але це буде результатом 1.
Ян Бойд

4
Чи є значення мовчки виправити введення типу 7, а не викидати якийсь виняток? Я маю на увазі, що, якщо якийсь інший біт коду потрапив на 7, коли він очікував лише 0 або 1, перш ніж ваш код виправив значення?
Чак ван дер Лінден

12

Ще одна форма вашого оригінального рішення:

v = Number(v == 0);

EDIT: Дякую TehShrike та Guffa за вказівку на помилку в моєму оригінальному рішенні.


4
Оператор == повертає булеве значення (а не ціле число) у багатьох системах. Це буде працювати лише в тому випадку, якщо v було визначено як ціле число, а мова була прохолодною при автоматичному передаванні з булевого в ціле число.
TehShrike

Дуже правильно. Я відповідав на питання в контексті javascript (як тег було позначено).
Курт Кейлор

@Kurt Kaylor: Javascript - це одна із систем, де оператор == повертає булеву форму, тому він не робить те саме, що оригінальне рішення.
Гуффа

@Guffa: Я користуюся тим, що javascript - це слабо типізована мова з неявним перетворенням типу (наприклад, 00.0000 '== 0, 0 == "", false == "", false == 0, 1 == правда тощо). Я можу використовувати повернене булеве значення так само, як і ціле число значення 0 або 1. Спробуйте, наприклад, оцінити "2 + true" в консолі javascript, ви отримаєте 3.
Kurt Kaylor

1
@Kurt Kaylor: Це працює лише в ситуаціях, коли ви змушуєте неявну конверсію. Спробуйте, наприклад, 'opacity:'+trueі ви закінчите opacity:trueзамість opacity:1.
Гуффа

11

Я б це зробив більш чітко.

Що vозначає?

Наприклад, коли v - деякий стан. Створіть статус об'єкта. У DDD об'єкт значення.

Реалізуйте логіку в цьому об'єкті значення. Тоді ви можете написати свій код більш функціональним способом, який можна читати. Переключення стану можна здійснити, створивши новий Статус на основі поточного стану. Після цього ваш об'єкт / логіка інкапсульований у вашому об'єкті, який ви можете випробувати. ЗначенняObject завжди незмінне, тому воно не має ідентичності. Тож для зміни значення варто створити нове.

Приклад:

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

6
над інженерією?
alejandro5042

6
+1 за те, що змушує мене сміятися
Деньші


10

Цього немає:

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

9

Оскільки це JavaScript, ми можемо використовувати унар +для перетворення в int:

v = +!v;

Це буде логічним NOTзначенням v(давання, trueякщо v == 0або falseякщо v == 1). Тоді ми перетворюємо повернене булеве значення у відповідне ціле представлення.



7

Ще один: v=++v%2

(в C це було б просто ++v%=2)

пс. Так, я знаю, що це подвійне призначення, але це лише необроблене перезапис методу C (який не працює, як є, тому що оператор попереднього збільшення JS не повертає значення.


3
Ваша версія C незаконна; ви не можете змінити результат ++оператора (це не значення). Що стосується v=++v%2, ви змінюєте vдвічі. Я не знаю, чи добре це визначено в JavaScript, але це не обов'язково. v = (v+1) % 2.
Кіт Томпсон

Принаймні, c++це так - оскільки оператор попереднього збільшення має пріоритет і змінює змінну "на місці", тому її можна використовувати як значення. Я думаю, що реалізація JS ++така, що її не можна трактувати як значення: / І так, це зайве, але я намагався показати лише інший метод - там вже розміщені кращі рішення :)
Адам Юрчик

3
+1. Можна записати як v = (v + 1)% 2.
niktrs

7

Якщо ви гарантуєте, що ваш внесок є або 1, або 0, ви можете використовувати:

v = 2+~v;

7

визначити масив {1,0}, встановити v до v [v], тому v зі значенням 0 стає 1, а vica навпаки.


Моє рішення правильне, якщо вам це не подобається, напишіть чому. Ваш коментар нікому не допомагає. Моє рішення читає змінну, на відміну від прийняття рішення. Для цього потрібно менше процесора.
С ..

5

Інший творчий спосіб зробити це, vприрівнявшись до будь-якої цінності, завжди повернеться 0або1

v = !!v^1;

3
два !!результати нічого не мають в логічній математиці, ви можете покласти !!!!туди і буде те саме, але в результаті 4 зайвих операцій
Алекс К

10
@ Алекс: !!буде кинутий на булінг . !!(1) === trueі!!(0) === false
nickf

1
@nickf: ага, тож я думаю v = Boolean(v^1), буде більш інформативним, дякую за пояснення - не думав про кастинг
Alex K

1
@ Алекс, "логічна математика"? Ось чому математики - погані програмісти. Не розумій мене; хороші програмісти також добре розуміють математику. Але це не має нічого спільного з логічною математикою. Це мовна конструкція, яка з урахуванням будь-якого виразу, принаймні у Javascript, !перетворить його на булеве. Додавання іншого !негативно скаже це буле. Кастинг тут неявний, і кінцевий результат працює. Немає потреби в -1.
Янік Рошон

1
Я зовсім не математик. ви можете спробувати це і побачити себе jsperf.com/javascript-boolean-test
Alex K

4

Якщо можливі значення для v - лише 0 і 1, то для будь-якого цілого числа x вираз: v = Math.pow ((Math.pow (x, v) - x), v); переключить значення.

Я знаю, що це некрасиве рішення, і ОП не шукала цього ... але я думала про ще одне рішення, коли була в лоо: P




1

Якщо є лише два значення, як у цьому випадку (0, 1), я вважаю, що марно використовувати int. Скоріше йдіть за булевими та працюйте в шматочках. Я знаю, що я припускаю, але у випадку перемикання між двома станами булевий здається ідеальним вибором.


1

Що ж, як ми знаємо, що тільки в 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/

Сподіваючись, що це допоможе вам :)


Це працює для перемикання значення, але значення змінюється не між 0 і 1, а між trueі false. Ви можете використовувати v == 0для визначення значення змінної в умові, але якщо ви хочете використовувати значення 0 або 1, вам потрібно буде використовувати щось на кшталт v == 0 ? 0 : 1або Number(v)отримати це. (Також ви можете використовувати v = !v;для перемикання між trueі false.)
Guffa

так, спасибі :) дякую :)
Vikash Pandey

0

v = число (! v)

Він додасть значення "Перевернуте булеве значення" у число, яке є бажаним результатом.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.