Krule
Krule

Reputation: 6476

Multiple conditions in a for loop

I am having a question regarding coffeescript for loop.

Single condition case is achieved by:

-> foo for foo in foos when foo is bar

and it produces:

(function() {
  var foo, _i, _len, _results;
  _results = [];
  for (_i = 0, _len = foos.length; _i < _len; _i++) {
    foo = foos[_i];
    if (foo === bar) _results.push(foo);
  }
  return _results;
});

which is perfect.

However, I have a case where there are multiple conditions involved and the construct above does not support them as far as I know. This one:

->
  for foo in foos
    if foo is bar
      foo
    else if foo isnt bar
      bar

does and it compiles into:

(function() {
  var foo, _i, _len, _results;
  _results = [];
  for (_i = 0, _len = foos.length; _i < _len; _i++) {
    foo = foos[_i];
    if (foo === bar) {
      _results.push(foo);
    } else if (foo !== bar) {
      _results.push(bar);
    } else {
      _results.push(void 0);
    }
  }
  return _results;
});

which is ok, but I was wondering if there is a way to get rid of extra else statement. Right now I added:

else
  return undefined

which prevents pushing to _results and it works.

So, is there a construct in coffeescript similar to the first example but for multiple conditions?

Upvotes: 1

Views: 1939

Answers (3)

Guillaume86
Guillaume86

Reputation: 14384

Given your snippets I would just use:

foo for foo in foos when foo is bar or foo isnt bar

but they're perhaps oversimplificated

Upvotes: 0

Trevor Burnham
Trevor Burnham

Reputation: 77436

The if...else solution looks perfectly fine to me. Remember that when is for actually skipping values. For instance,

num for num in [1, 2, 3, 4] when num % 2 is 0

will give you

[2, 4]

By contrast, if you want the loop to return a list with the same length as the input, you should be using a conditional inside—either if...else or switch.

Upvotes: 2

Brian Genisio
Brian Genisio

Reputation: 48167

I wonder if you can play with it like this:

-> select foo for foo in foos when foo matches bar

It will require a function to handle select and matches but it would give you the syntax you are looking for:

(function() {
  var foo, _i, _len, _results;
  _results = [];
  for (_i = 0, _len = foos.length; _i < _len; _i++) {
    foo = foos[_i];
    if (foo(matches(bar))) _results.push(select(foo));
  }
  return _results;
});

Upvotes: 0

Related Questions