1

In several places, I have loops over a pre-defined set of values.

My current code is:

for (var period in {'today':true,'yesterday':true,'this week':true,'last week':true,'this month':true,'last month':true}) {
  ...    
}

It works, but is there a prettier way of doing this?

(period needs to be the values, not the index, otherwise I would use an array.)

fadedbee
  • 42,671
  • 44
  • 178
  • 308
  • possible duplicate of [Iterating Over An Array in JavaScript](http://stackoverflow.com/questions/5167323/iterating-over-an-array-in-javascript) – simonzack Oct 23 '14 at 13:04
  • 1
    I don't think this is a dupe, since it is specifically about literal values, which prevent (or at least complicate) the use of the old standard `for (i in varname) { item=varname[i];...}` idiom. – Mark Reed Oct 23 '14 at 13:24
  • No, it's not a dup, I want period to successively contain the values 'today', 'yesterday', etc. – fadedbee Oct 24 '14 at 08:10

3 Answers3

2

Yes, assuming you don't need to worry about older Javascript engines (like IE<=8):

['today','yesterday','this week','last week',
 'this month','last month'].forEach(function(period) {
 ...
})
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • OP says: "(period needs to be the values, not the index, otherwise I would use an array.)" – simonzack Oct 23 '14 at 12:55
  • 1
    And in the above code, `period` is the value, not the index. The problem isn't the use of an array *per se*; the problem is that `for varname in array` sets `varname` to the indexes rather than the values. `forEach` doesn't share that problem. – Mark Reed Oct 23 '14 at 12:56
  • 1
    Yes, and in this case `period` is the value. – Aadit M Shah Oct 23 '14 at 12:56
  • I suppose OP didn't phrase his question clearly then, as his example iterates the keys. I've retracted my downvote. – simonzack Oct 23 '14 at 12:58
  • OP wants to iterate over the values `today`, `yesterday`, etc. In his code he used an object with those as the keys because that's what `for`...`in` iterates over, but you can also use an array with `forEach`. The results are identical; the details of key vs value only matter for explaining why he didn't use an array in the first place. – Mark Reed Oct 23 '14 at 13:00
1

A way of doing this in ES6 is:

for (var period of ['today', 'yesterday', 'this week', 'last week', 'this month', 'last month']) {
    // ...        
}

This is supported in firefox. If you js engine doesn't support it then use a ES6 transpiler or you'll need to fallback to older solutions.

simonzack
  • 19,729
  • 13
  • 73
  • 118
1

I would do this:

var timePeriod = [ "today"
                 , "yesterday"
                 , "this week"
                 , "last week"
                 , "this month"
                 , "last month"
                 ];

for (var i in timePeriod) {
    with ({ period: timePeriod[i] }) {
        ...
    }
}

This has two advantages over @MarkReed's solution:

  1. It works in all browsers.
  2. It's faster because no function is ever called.

In addition, the use of the with statement prevents the infamous for loop clousure problem.

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299