kharandziuk
kharandziuk

Reputation: 12900

Strange behavior in coffeescript for loop

I'm trying to iterate over array in CoffeeScript but there is some kind of strange behavior. For example look on this code:

kapa = [1]
for i in kapa
    console.log 't'
    kapa.push 1

I expect that this code produce an infinite sequence of 't' symbols in console. But in reality it prints only one 't'. What is the logic behind this behavior? And how can I achieve expected behavior? Explanation:

elements= [1]
for i in elements
    proccess(element)
    if someCond
      newElement = ...
      element.push(newElement) #

I want to achieve behavior when all newElements will be processed

Upvotes: 0

Views: 40

Answers (2)

go-oleg
go-oleg

Reputation: 19480

The reason it only prints it out once is because that coffeescript compiles to this JS:

var i, kapa, _i, _len;

kapa = [1];

for (_i = 0, _len = kapa.length; _i < _len; _i++) {
  i = kapa[_i];
  console.log('t');
  kapa.push(1);
}

So it calculates the length of the array in the beginning and doesn't get updated when you kapa.push(1). I would say this is expected behavior and moreover, modifying an array while you are iterating over it sounds like a bad idea. In other languages like Java, you would get an Exception if you tried to do that.

If you really want it to print infinite t and push 1 onto the array every time, you would need an infinite loop:

kapa = [1]
while true
  console.log( 't' )
  kapa.push( 1 )

(but thats obviously discouraged and I'm not sure why you would want that behavior)

UPDATE

Based on the updated question, you could use the array as a queue-like structure

elements= [1]
while nextElem = elements.shift()
    proccess(nextElem)
    if someCond
      newElement = ...
      elements.push(newElement)

Upvotes: 1

Sylvain Leroux
Sylvain Leroux

Reputation: 52000

Given your added explanation, maybe you are using your array as a queue:

elements= [1]
while elements.length
    proccess(elements.shift())
    if someCond
      newElement = ...
      element.push(newElement)

Notice the use of a while loop (whose end condition is evaluated at each iteration), and elements.shift that removes the first element of the queue.

Upvotes: 1

Related Questions