Я хочу переключить переменную между 0 и 1. Если это 0, я хочу установить 1, иначе, если это 1, я хочу установить 0.
Это настолько фундаментальная операция, что я пишу так часто, что мне хотелось бы исследовать самый короткий и ясный способ ее выполнения. Вот мой лучший пока:
v = (v == 0 ? 1 : 0);
Вы можете улучшить это?
Изменить: вопрос заключается в том, как написать вышеупомянутое утверждение с наименьшим количеством символов при сохранении ясности - как это «не реальный вопрос»? Это не было задумано как упражнение по коду для гольфа, хотя некоторые интересные ответы были получены от людей, относящихся к нему как к гольфу - приятно видеть, что гольф используется конструктивно и заставляет задуматься.
javascript
variables
coding-style
toggle
Олли Гласс
источник
источник
v = +!v;
Ответы:
Вы можете просто использовать:
Это, конечно, предполагает, что переменная инициализирована должным образом, то есть имеет значение 0 или 1.
Другой метод, который короче, но использует менее распространенный оператор:
Редактировать:
Быть понятным; Я никогда не подходил к этому вопросу как к кодовому гольфу, просто чтобы найти краткий способ решения этой задачи, не используя никаких скрывающих приемов, таких как побочные эффекты операторов.
источник
v ^= 1
должен прекратить программировать, немного резок, я думаю. Как было сказано ранее, это не один из наиболее распространенных операторов, и он не делает то же самое, что иv = v ^ 1
. Также оператор означает что-то совершенно другое на разных языках (VB). Да, быстрый просмотр скажет вам, что это оператор XOR, и вы поймете, что он делает, но для многих это может быть неочевидно на первый взгляд. Я не думаю, что это означает, что вам нужно бросить свою работу.Так
0
как являетсяfalse
значением и1
являетсяtrue
значением.Если вы с удовольствием используете
true
иfalse
вместо цифрили если они должны быть числами:
источник
+
перед этим!
. Оооо это выглядит так грязно! но круто: pswitch(v){ case 0 ...
или если (v == 0) или если v === 0. Вы меняете его результат в дополнение к его подходу ...({v :+! v}).v
.+
знаком! ¯ \ _ (ツ) _ / ¯v = (v ? 0 : 1)
понятный и идиоматичный JS.v = (v + 1) % 2
и если вам нужно перебрать больше значений, просто измените2
на(n + 1)
. Скажем, вам нужно цикл 0,1,2 просто сделатьv = (v + 1) % 3
.источник
const
переменную вместо магических чисел 2, 3, ...++v % 3
если вы хотите перебрать 0, 1, 2Вы можете написать для него функцию и использовать ее следующим образом:
v = inv(v)
источник
inv
функцию: P)inv
описательным именем?Если вас не волнует какая-либо возможность, кроме 1:
В приведенном выше случае v будет равен 1, если v равно 0, false, undefined или null. Будьте осторожны, используя такой подход - v будет 0, даже если v "привет мир".
источник
v = v ? 0 : 1
.Линии вроде
v = 1 - v
, илиv ^= 1
илиv= +!v
все выполнят работу, но они составляют то, что я бы назвал хаки. Это не красивые строки кода, а дешевые трюки для достижения желаемого эффекта.1 - v
не сообщает "переключить значение между 0 и 1". Это делает ваш код менее выразительным и создает место (пусть и небольшое), где другой разработчик должен будет проанализировать ваш код.Вместо этого такая функция как бы
v = toggle(v)
сообщает о намерении с первого взгляда.источник
v=1-v
не связывает тумблер?1-v
может общаться действительно переключаться, но это единственное, что он сообщает. Например, он может также передавать линию с нулем вv=1
или зеркальное преобразование с центром вv=0.5
. В этом смысле это относительно неоднозначно. Это правда, что знание, котороеv
может только когда-либо быть0
или1
ограничивать его предполагаемое значение, но заставляет других разработчиков (или ваше будущее Я) понять этот контекст, прежде чем сможет понять эту простую линию. Вы не можете быть намного яснее, чемv = toggle(v)
v ^= 1
Совершенно ясно, если вы понимаете логические операции, что вам лучше, если вы программист. Я думаю, что это разница между этим иv=1-v
; одна - логическая операция, другая - арифметическая, и мы пытаемся представить логическое понятие, а не математическое.v ^= 1
есть некоторая двусмысленность, хотя, поскольку это может интерпретироваться как побитовый xor.( Честность и математическая целостность - учитывая количество голосов по этому «ответу» - заставили меня отредактировать этот ответ. Я задержался как можно дольше, потому что он был задуман как короткое замечание, а не как «глубокий», так что любое объяснение казалось противоречащим цели. Однако комментарии ясно дают понять, что я должен быть ясным, чтобы избежать недоразумений. )
Мой оригинальный ответ:
Формулировка этой части спецификации:
подразумевает, что наиболее точным решением является:
Во- первых, признание: я сделал , чтобы мои дельта - функции спутать. Дельта Кронекера была бы немного более подходящей, но не намного, поскольку я хотел что-то, что было бы независимым от домена (дельта Кронекера в основном используется только для целых чисел). Но я действительно не должен был использовать дельта-функции вообще, я должен был сказать:
Позвольте мне уточнить. Напомним , что функция является тройной, (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 dμ имеет смысл и, в некотором неопределенном смысле, «среднее» из F над X .
Учитывая меру в наборе, можно определить «меру» для подмножеств этого набора. Это делается путем присвоения подмножеству интеграла его характеристической функции (при условии, что это измеримая функция). Это может быть бесконечным или неопределенным (два слегка различаются).
Есть много мер вокруг, но есть два, которые здесь важны. Одним из них является стандартная мера на реальной линии, ℝ. Для этой меры тогда ∫ ℝ f dμ - это почти то, чему вас учат в школе (исчисление все еще преподают в школах?): Суммируйте маленькие прямоугольники и выбирайте все меньшую и меньшую ширину. В этой мере мерой интервала является его ширина. Мера точки равна 0.
Другая важная мера, которая работает на любом множестве, называется точечной мерой . Он определяется так, что интеграл функции является суммой ее значений:
∫ X f dμ = ∑ x ∈ X f (x)
Эта мера назначает каждому одноэлементному набору меру 1. Это означает, что подмножество имеет конечную меру тогда и только тогда, когда оно само является конечным. И очень немногие функции имеют конечный интеграл. Если функция имеет конечный интеграл, она должна быть ненулевой только на счетном количестве точек. Таким образом, подавляющее большинство функций, которые вы, вероятно, знаете, не имеют конечного интеграла по этой мере.
А теперь к дельта-функциям. Давайте возьмем очень широкое определение. У нас есть измеримое пространство (X, μ) (так что это множество с мерой на нем) и элемент ∈ X . Мы «определяем» дельта-функцию (в зависимости от a ) как «функцию» δ a : X → ℝ со свойством δ a (x) = 0, если x x a и ∫ X δ a dμ = 1 .
Самый важный факт, который можно использовать для этого, заключается в следующем: дельта-функция не обязательно должна быть функцией . Это не правильно определено: Я не сказал , что & delta (а) есть.
Что вы делаете в этот момент, зависит от того, кто вы есть. Мир здесь делится на две категории. Если вы математик, вы говорите следующее:
Если вы не математик, вы говорите следующее:
Обидев теперь мою аудиторию, я продолжу.
Дираковская дельта обычно берется дельта - функция точки (часто 0) в реальном соответствии со своей стандартной мерой. Так что те, кто жалуется в комментариях о том, что я не знаю моих дельт, делают это, потому что они используют это определение. Я приношу им свои извинения: хотя я могу выкрутиться из этого, используя защиту Математика (популяризируемую Шалтай-Болтай : просто переопределить все так, чтобы она была правильной), использование стандартного термина для обозначения чего-то другого - это плохая форма.
Но есть дельта - функция , которая делает то , что я хочу, чтобы это сделать , и это то , что мне нужно здесь. Если взять меру точки на множество X , то есть является подлинной функция δ в : X → ℝ , которая удовлетворяет критерии для дельта - функции. Это потому, что мы ищем функцию X → ℝ, которая равна нулю за исключением a и такая, что сумма всех ее значений равна 1. Такая функция проста: единственная недостающая часть информации - это ее значение в a , и чтобы получить сумму, равную 1, мы просто присваиваем ей значение 1. Это не что иное, как характеристическая функция на {a} . Затем:
∫ X δ дМ = Σ х ∈ X , δ (х) = δ (а) = 1.
Таким образом, в этом случае для одноэлементного множества характеристическая функция и дельта-функция совпадают.
В заключение, здесь есть три семейства «функций»:
Второй из них является наиболее общим , как любой из других является примером этого при использовании измерения точки. Но первое и третье имеют то преимущество, что они всегда являются подлинными функциями. Третий фактически является частным случаем первого для определенного семейства доменов (целых чисел или некоторого их подмножества).
Таким образом, в конце концов, когда я первоначально написал ответ , который я не думая , правильно (я бы не пошел так далеко, чтобы сказать , что я был смущен , как я надеюсь , что я только что показал , я действительно знаю , что я говорю о том, когда Я действительно сначала думаю, я просто не очень много думал). Обычное значение дельты Дирака здесь не то, что нужно, но один из пунктов моего ответа заключался в том, что входная область не была определена, поэтому дельта Кронекера также была бы неправильной. Таким образом, лучшим математическим ответом (к которому я стремился) была бы характеристическая функция.
Я надеюсь, что это все ясно; и я также надеюсь, что мне больше никогда не придется писать математическую часть, используя объекты HTML вместо макросов TeX!
источник
Вы могли бы сделать
Уменьшение устанавливает значение в 0 или -1, а затем
Math.abs
преобразует -1 в +1.источник
v = Math.round(Math.sin(Math.PI/(v+3)));
v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));
: Dv = 1
тоv = Math.Abs(-1)
что +1. Еслиv = 0
то,v = Math.Abs(-0)
что равно 0.в общем, когда вам нужно переключиться между двумя значениями, вы можете просто вычесть текущее значение из суммы двух значений переключения:
источник
v
он поврежден, он внезапно начнет переключаться между двумя различными значениями. (Просто кое-что рассмотреть ...)v
обычно используется для попеременного выполнения двух состояний из списка из трех или более состояний, то повреждениеv
может привести к тому, что программа поочередно выполнит два совершенно разных состояния - это может привести к неожиданным и нежелательным результатам. Урок, который можно извлечь из этого: всегда проверяйте достоверность своих данных.Если это должно быть целое число 1 или 0, то то, как вы это делаете, хорошо, хотя скобки не нужны. Если эти a будут использоваться как логические значения, то вы можете просто сделать:
источник
Достаточно !
источник
v = (v==0 ? 1 : 0);
» . Все остальные находят разные способы игры в гольф; и на самом деле не отвечая на вопрос. Вот почему я проголосовал за этот ответ.Список решений
Есть три решения, которые я хотел бы предложить. Все они преобразовать любое значение
0
(если1
, иtrue
т.д.) , или1
(если0
,false
, иnull
т.д.):v = 1*!v
v = +!v
v = ~~!v
и еще один, уже упомянутый, но умный и быстрый (хотя работает только для
0
s и1
s):v = 1-v
Решение 1
Вы можете использовать следующее решение:
Это сначала преобразует целое число в противоположное логическое значение (
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 было другое решение, которое работает как мое:
Он также сначала делает логическое значение из исходного значения, но использует
+
вместо1*
преобразования его в целое число. Результат точно такой же, но обозначение короче.Решение 3
Другой подход заключается в использовании
~~
оператора:Это довольно редко и всегда конвертируется в целое число от логического.
источник
+
чтобы преобразовать ее в число, что+!v
эквивалентно вашему решению (решение jAndy в комментариях ОП).1*
может быть заменено+
при попытке преобразовать логическое значение в целое число. Все остальное в моем ответе остается прежним. Ответ Энди правильный, но мой более подробный. Я добавлю его / ее решение в мой ответ.Подводя итог другому ответу, комментарию и собственному мнению, я предлагаю объединить две вещи:
Вот функция, которую вы можете поместить в библиотеку или обернуть в плагин для другой Javascript Framework.
И использование просто:
Преимущества:
источник
function toggle(i){ return i == 0 ? 1 : 0 }
?Я не знаю, почему вы хотите создать свои собственные логические выражения? Мне нравятся прикольные синтаксисы, но почему бы не написать понятный код?
Это не самое короткое / самое быстрое, но самое ясное (и читаемое для всех) использование хорошо известного состояния if / else:
Если вы хотите быть действительно понятным, вы должны использовать для этого логические числа вместо цифр. Они достаточно быстры для большинства случаев. С логическими значениями вы можете просто использовать этот синтаксис, который выиграет в краткости:
источник
=== 0
. При вводе выборки7
правильный вывод -0
это вывод1
.Еще одна форма вашего оригинального решения:
РЕДАКТИРОВАТЬ: Спасибо TehShrike и Guffa за указание на ошибку в моем первоначальном решении.
источник
'opacity:'+true
и вы получитеopacity:true
вместоopacity:1
.Я бы сделал это более явным.
Что
v
значит?Например, когда v некоторое состояние. Создать объект Status. В DDD объект значения.
Реализуйте логику в этом объекте значения. Тогда вы можете написать свой код более функциональным способом, который будет более читабельным. Переключение статуса может быть сделано путем создания нового статуса на основе текущего статуса. Ваша инструкция / логика if затем инкапсулируется в ваш объект, который вы можете протестировать. ValueObject всегда неизменен, поэтому у него нет идентификатора. Таким образом, чтобы изменить его значение, вы должны создать новый.
Пример:
источник
Еще один способ сделать это:
источник
Это отсутствует:
Он также работает как Round Robin:
Или
Прелесть последнего решения, оно работает и со всеми другими ценностями.
Для очень особого случая, например, для получения (изменяющегося) значения
undefined
, этот шаблон может быть полезен:источник
Поскольку это JavaScript, мы можем использовать унарный
+
для преобразования в int:Это будет логическое
NOT
значениеv
(давая,true
еслиv == 0
илиfalse
еслиv == 1
). Затем мы конвертируем возвращенное логическое значение в соответствующее целочисленное представление.источник
Только для ударов:
v = Math.pow(v-1,v)
также переключается между 1 и 0.источник
Еще:
v=++v%2
(в С было бы просто
++v%=2
)пс. Да, я знаю, что это двойное присваивание, но это просто необработанное переписывание метода Си (который не работает как есть, потому что оператор предварительного приращения JS не возвращает lvalue.
источник
++
оператора (это не lvalue). Что касаетсяv=++v%2
, вы модифицируетеv
дважды. Я не знаю, хорошо ли это определено в JavaScript, но это не обязательно.v = (v+1) % 2
,c++
оно и есть - потому что оператор предварительного увеличения имеет более высокий приоритет и изменяет переменную «на месте», поэтому его можно использовать как lvalue. Я думаю, что реализация JS++
такова, что она не может рассматриваться как lvalue: / Да, это избыточно, но я пытался показать только другой метод - уже есть лучшие решения :)Если вы уверены, что ваш ввод 1 или 0, то вы можете использовать:
источник
определить массив {1,0}, установить v в v [v], поэтому v со значением 0 становится 1, и наоборот.
источник
Другой творческий способ сделать это,
v
равный любому значению, всегда вернет0
или1
источник
!!
результата ничего не!!!!
дают в логической математике, вы можете положить туда и будете такими же, но в результате 4 ненужных операции!!
приведёт к булу.!!(1) === true
и!!(0) === false
v = Boolean(v^1)
было бы более информативно, спасибо за объяснение - не думал о кастинге!
преобразует его в логическое значение. Добавление другого!
отменит это логическое значение. Приведение здесь неявно, и конечный результат работает. Там нет необходимости для -1.Если возможными значениями для v являются только 0 и 1, то для любого целого числа x выражение: v = Math.pow ((Math.pow (x, v) - x), v); будет переключать значение.
Я знаю, что это уродливое решение, и ОП не искал этого ... но я думал о другом решении, когда был в туалете: P
источник
Не проверено, но если вы после логического, я думаю,
var v = !v
будет работать.Ссылка: http://www.jackfranklin.co.uk/blog/2011/05/a-better-way-to-reverse-variables
источник
будет работать для v = 0 и v = 1; и переключать состояние;
источник
Если есть только два значения, как в этом случае (0, 1), я полагаю, что расточительно использовать int. Скорее идите для логического и работать в битах. Я знаю, что предполагаю, но в случае переключения между двумя состояниями логическое значение кажется идеальным выбором.
источник
Ну, поскольку мы знаем, что в javascript только это логическое сравнение также даст ожидаемый результат.
т.е.
v = v == 0
достаточно для этого.Ниже приведен код для этого:
JSFiddle: https://jsfiddle.net/vikash2402/83zf2zz0/
Надеюсь, это поможет вам :)
источник
true
иfalse
. Вы можете использоватьv == 0
для определения значения переменной в условии, но если вы хотите использовать значение 0 или 1, вам нужно будет использовать что-то вродеv == 0 ? 0 : 1
или,Number(v)
чтобы получить это. (Кроме того, вы можете использоватьv = !v;
для переключения междуtrue
иfalse
.)Он наберет приведенное значение Inverted Boolean в Number, которое является желаемым выходным значением.
источник