9
if (Progress.bar.status == 'finished' || Progress.bar.status == 'uploading'){
  //code here
}

How do I shorten this? I'd like to write it without having to repeat Progress.bar.status twice.

Something along the lines of:

Progress.bar.status == ('finished' or 'uploading').
Rich
  • 5,603
  • 9
  • 39
  • 61

4 Answers4

16

I like lookup tables:

if ({finished:1, uploading:1}[Progress.bar.status]){
  //code here
}

this uses an object to code two or more options, and even side-steps quoting every choice. its also very fast since the object can be cached and there is no comparison logic or methods to invoke, just fast property access driving the flow...

do note that in some cases, you might want to use Object.create(null) and then merge/extend that blank object with your options, if you absolutely must avoid false-positives for "hasOwnProperty", "valueOf", "toString", "toLocaleString", "constructor", and a few double-underscore extensions. it's not often an issue, but it is something to keep in mind. if you can live without feeding your if those keywords, or building a cached collection of choices from Object.create(), it's a fast and simple way to code "one of the above" flows.

dandavis
  • 16,370
  • 5
  • 40
  • 36
  • Nice one, didn't know about it. – hsz Jun 22 '15 at 07:52
  • Why do you add _1_ in **{finished:1, uploading:1}**? – The Reason Jun 22 '15 at 07:53
  • 1
    `1` is a value which will satisfy the `if(` when the key matches, and is quick to type. any thruthy value will do, but for many progs, `1` means yes and `0` means no... – dandavis Jun 22 '15 at 07:53
  • I feel a better word would be enumerations – Downgoat Jun 22 '15 at 07:54
  • 1
    @vihan1086: enumerations typically convert to different numbers, the code above just needs to convert to booleans. however, lookup tables can also mimic enums: `TRANS={opaque:1, faded:0.8, ghost: 0.5, clear:0}; elm.style.opacity=TRANS.faded;` lookups can even replace 1:1 `switch` operations with a potentially recyclable choice pool (named var instead of anon obj) and typically faster execution: `elm.style.color={r:'red', g:'#040', b:'blue'}[item.colorCode];` – dandavis Jun 24 '15 at 09:19
  • I like it. Readable and terse. – Rich Jul 21 '15 at 12:34
4

Make with the wanted strings an array, apply a search for the index of the array. The result is -1 for not found and 0 ... n for a found string. to make this short and while we need only the 0 ... n result, apply a bitwise not to the result (https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) :

value  ~value   boolean
 -1  =>   0  =>  false
  0  =>  -1  =>  true
  1  =>  -2  =>  true
  2  =>  -3  =>  true
  and so on 

In code all together it looks like this:

if (~['finished', 'uploading'].indexOf(Progress.bar.status)) {
    // code here
}
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
4

I can suggest working with enumerations then a switch() statement:

var Status = {
    Finished: 'finished', 
    Uploading: 'uploading'
};

switch (Progress.bar.status) {
    case Status.Finished:
    case Status.Uploading:
      //code here
      break;
}

More code initially, but more flexible and readable.

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
0

I know, that extending native object is a taboo, but:

String.prototype.eqOr = function(){
  var i;
  var str = this.toString();
  for(i=0; i< arguments.length; i++){
    if(arguments[i] === str){
      return true;
    }
  }
  return false;
}

if(Progress.bar.status.eqOr('finished', 'uploading')){
   //code here
}

v2.0, thanks Ja͢ck

String.prototype.eqOr = function(){
   return [].indexOf.call(arguments, this.toString()) !== -1;
}
Roland Szabo
  • 153
  • 5