Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×

Javascript Mod/API: 2 Questions on || meaning

I was having a devil of a time trying to figure out how to iterate/loop through records in a section of a character sheet and finally reluctantly went to AI as suggested by Keith some time ago. It really helped me. But I have a question about the symbol ||.  Question 1 I thought it was used for "or" in an if statement? But a snippet I get from chatGPT is: let eqName = getAttrByName(         charID, `repeating_equipment_${id}_equipment_item` ) || ""; This seems to be using || as an nvl function (in Oracle-ese), i.e. if null or no value fount, use "". Is that a correct interpretation? Question 2 Am I correct in thinking || can be used as an OR in an if statement?  For example, if I have a bunch of ELSE IFs:                             if (eqName.includes("arrow")) { isMissile = "y"; } else if (eqName.includes("bolt")) { isMissile = "y"; } else if (eqName.includes("quarrel")) { isMissile = "y"; } else if (eqName.includes("rock")) { isMissile = "y"; } else if (eqName.includes("bullet")) { isMissile = "y"; } else { isMissile = "n"; } Can I do this, instead? if (eqName.includes("arrow") || (eqName.includes("bolt")) || (eqName.includes("quarrel")) || (eqName.includes("rock")) || (eqName.includes("bullet")) { isMissile = "y"; } else { isMissile = "n"; } Is || more efficient than else if? Thanks. :-)
1779411961
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
yes the double pipe just means if the left side is truthy, use that, otherwise use the right side. so you have several possible states and outputs. To demonstrate them I'll use null/false as falsy values and true/"some string" as truthy values. true || "some string" => true true || false => true false || "some string" => "some string" null || false => false The returned value is always the first truthy value, or the final value if none of them are truthy. This is what the logical OR operator means in programming. See mdn for full details . For your specific question 2, assuming that all of those if branches do indeed have the exact same contents, then yes you could use the or instead of the else if chain. I'm not sure there's an efficiency to be gained, but it will be more more readable most likely.
1779416401
timmaugh
Pro
API Scripter
Hey, Tim...  As Scott said, you have the right understanding of the logical OR operator... but I have a couple of considerations about what you're doing... getAttrByName is going to return the contents of the attribute, which will be a string. (The example from your first question shows that your code enforces that what you assign to your eqName variable is going to be a string (because of the logical OR). If it is really a string, you can significantly consolidate your code... down to a single "if" statement by having the array of "isMissile" tripping values in an array. All you have to do is turn the comparison around: if(["arrow","bolt","quarrel","rock","bullet"].includes(eqName)) {     isMissile = 'y'; } else { isMissile = 'n'; } In fact, you could default the isMissile variable to be 'n' when you declare it, then only change it based on the same logic as above: let isMissile = 'n'; if(["arrow","bolt","quarrel","rock","bullet"].includes(eqName)) { isMissile = 'y'; } Depending on how readable it is (or how comfortable you are with it), you could use a ternary expression  and get everything done in one statement: let isMissile = ["arrow","bolt","quarrel","rock","bullet"].includes(eqName) ? 'y' : 'n'; It can be prettier (and easier to read) with line breaks: let isMissile = ["arrow","bolt","quarrel","rock","bullet"].includes(eqName)     ? 'y'     : 'n'     ; If eqName truly is an array (rather than a string), then you can still shorten your code, this time with the Array.some() method... but since I don't see you converting a string into an array, I won't confuse the examples, above, with something that likely doesn't apply. ...of course, if it *does* apply, post back and we can help you through the building of an evaluation using Array.some() 
Scott C. said: yes the double pipe just means if the left side is truthy, use that, otherwise use the right side. so you have several possible states and outputs. To demonstrate them I'll use null/false as falsy values and true/"some string" as truthy values. true || "some string" => true true || false => true false || "some string" => "some string" null || false => false The returned value is always the first truthy value, or the final value if none of them are truthy. This is what the logical OR operator means in programming. See mdn for full details . For your specific question 2, assuming that all of those if branches do indeed have the exact same contents, then yes you could use the or instead of the else if chain. I'm not sure there's an efficiency to be gained, but it will be more more readable most likely. Thanks Scott. Going nuts with pipes now!!! :-)
timmaugh said: Hey, Tim... If it is really a string, you can significantly consolidate your code... down to a single "if" statement by having the array of "isMissile" tripping values in an array. All you have to do is turn the comparison around: if(["arrow","bolt","quarrel","rock","bullet"].includes(eqName)) {     isMissile = 'y'; } else { isMissile = 'n'; } In fact, you could default the isMissile variable to be 'n' when you declare it, then only change it based on the same logic as above: let isMissile = 'n'; if(["arrow","bolt","quarrel","rock","bullet"].includes(eqName)) { isMissile = 'y'; } Depending on how readable it is (or how comfortable you are with it), you could use a ternary expression  and get everything done in one statement: let isMissile = ["arrow","bolt","quarrel","rock","bullet"].includes(eqName) ? 'y' : 'n'; It can be prettier (and easier to read) with line breaks: let isMissile = ["arrow","bolt","quarrel","rock","bullet"].includes(eqName)     ? 'y'     : 'n'     ; If eqName truly is an array (rather than a string), then you can still shorten your code, this time with the Array.some() method... but since I don't see you converting a string into an array, I won't confuse the examples, above, with something that likely doesn't apply. ...of course, if it *does* apply, post back and we can help you through the building of an evaluation using Array.some()  Thanks, Tim, it definitely is a string. I find it neat that  if(["arrow","bolt","quarrel","rock","bullet"].includes(eqName)) is pretty opposite what I was writing with the eqName coming afterwards instead of first. There are square brackets, of course. All great stuff, the rest of it. I will see how I can shorten up my code. All the best,