21

I want to do something like

if(something.val() == 'string1')
{
     something.val('string2');
}
else if(something.val() == 'string2')
{
    something.val('string1')
}

But in one line of code. I can't quite remember how it's done, but it involves question marks and colons...

Bojangles
  • 99,427
  • 50
  • 170
  • 208

10 Answers10

39

Try:

something.val(something.val() == 'string1' ? 'string2' : 'string1');

It is called a ternary expression.

nawfal
  • 70,104
  • 56
  • 326
  • 368
Matthew Manela
  • 16,572
  • 3
  • 64
  • 66
10

Look ma, no ternary operator!

The following works because Javascript short circuits boolean expressions.

If something == string1 then evaluate string2 -- since string2 is a truthy value and the next expression involves the OR operation there is no need to continue. Stop and return string2.

If something !== string1 then it will skip the next operand because if it is false, there is no point in evaluating the next operand (with AND). It will "jump" to the OR operation and return string1.

function toggleString(something, string1, string2) {
   return something == string1 && string2 || string1;
}

something.val(toggleString(something.val(), "string1", "string2"));

If you want the assignment done:

function toggleValue(something, string1, string2) {
   something.val(something.val() == string1 && string2 || string1);
}

toggleValue(something, "string1", "string2"); // something is a jQuery collection

In the end however, I would end up using the ternary operator because this solution might be unclear to other programmers. If you come from Java or other languages, you may expect the function to return a boolean because of all the boolean operators.

Cristian Sanchez
  • 31,171
  • 11
  • 57
  • 63
  • Ok, so you still have to assign to `something` in there somewhere. You didn't assign, you only compared. – jcolebrand Sep 27 '10 at 20:56
  • @Daniel ... yeah, I know that. My point was more like the ternary reads faster than that, and you still have to show the assignment in your clever post ;) – jcolebrand Sep 27 '10 at 20:58
  • +1 clever solution, though you should explain *why* this works. – Daniel Vandersluis Sep 27 '10 at 20:59
  • Thanks - a bit long winded for what I want as I'm doing this inline, but handy nonetheless! – Bojangles Sep 27 '10 at 21:00
  • @drachenstern: Since everybody else posted the ternary operator solution there really is no point in posting the same thing. This function will toggle between the two values based on the something. How he uses it (if at all) will be up to him -- it's would be up to him to modify it if he wants to make the function easier to use. Besides, `something` is meant to be a string (which are immutable) so I wouldn't be able to change it anyways. I'll add the explanation and add the version that does the assignment to satisfy *you people*. – Cristian Sanchez Sep 27 '10 at 21:05
  • lol@you people ... I added +1 for the clever. I just wondered if it was too clever as a two line post (ignoring brackets) ... and as for the "since everybody else posted the ternary" ~ it was what he asked for, and I was the second person to actually reply, but yeah, it was quite an avalanche of the same answer repeatedly. – jcolebrand Sep 27 '10 at 21:15
  • See my answer towards the bottom if you're interested in making this a jquery function so you can call $('input').toggleVal('str2','str2'); – fehays Sep 27 '10 at 21:21
6

Another way to do it using object properties:

{ 'string1': 'string2', 'string2': 'string1' }[value]

As in the question:

something.val(
  { 'string1': 'string2', 'string2': 'string1' }[something.val()]
)
kolossal7
  • 155
  • 3
  • 9
  • This is an extremely question, but if you are going to answer it perhaps you could add an example implementation, you will notice most upvoted answers do. Cheers – webLacky3rdClass Feb 02 '17 at 19:36
  • 1
    Very clever! I'd be tempted to use it but for two reasons; 1, it's not immediately clear what this code does and 2, nowadays I'd use ES6 destructuring like `[ string2, string1 ] = [ string1, string2 ]` – Bojangles Feb 03 '17 at 09:36
  • @Bojangles two switch two strings, yes, but how would you use ES6 features for your original question? – kolossal7 Feb 03 '17 at 13:16
3

How about using @Daniel's code along with a jquery function:

$.fn.toggleVal = function (str1, str2) {
     return this.val(this.val() == str1 && str2 || str1);
};
$("input").toggleVal('string 1', 'string 2');
fehays
  • 3,147
  • 1
  • 24
  • 43
  • 1
    There really is no benefit for using my solution over a ternary operator - I just thought it would be nice to offer an alternate version :). Nice though! isn't `this` already a jQuery object? So there is no need to wrap it with the `$` function. Also, jQuery probably returns `this` when calling `val` as a setter, so you might be able to merge those two lines into a single one line return statement. – Cristian Sanchez Sep 27 '10 at 21:27
  • Indeed you are correct. Thanks for the tip :) I will update the code. And I like yours over the ternary operator because question marks scare me :P – fehays Sep 27 '10 at 21:44
  • That is the right answer – Sam Feb 07 '23 at 22:03
2

Though, the solutions with a ternary operator are the most readable, you could also use xor from Lodash:

x = _.xor([a, b], [x])[0]

For your specific case:

something.val(_.xor(['s1', 's2'], [something.val()])[0]);

Ref: https://lodash.com/docs/4.17.10#xor

Thierry
  • 7,775
  • 2
  • 15
  • 33
1

You mean to use the ternary operator:

something.val((something.val() == 'string1') ? 'string2' : 'string1');
Mike Axiak
  • 11,827
  • 2
  • 33
  • 49
1

As of jQuery 1.4, you can do this:

something.val(function(index, val) {
    return val == 'string1' ? 'string2' : 'string1';
});
Eric
  • 95,302
  • 53
  • 242
  • 374
0
 something.val( something.val() == 'string1'? 'string2' : 'string1' );

or for clarification

val astring = something.val() == 'string1'? 'string2' : 'string1';
something.val( astring );
jcolebrand
  • 15,889
  • 12
  • 75
  • 121
0

My way was this in a similar situation:

let value = 0

const toggleTwoValues = () => 
  value === 0 ? value = 1 : value = 0
-1
something.val(something.val() == 'string1' ? 'string2' : 'string1');
Conner
  • 30,144
  • 8
  • 52
  • 73
James Curran
  • 101,701
  • 37
  • 181
  • 258