# How to avoid duplication in a for loop when "initialization step" is identical to "update step"?

I often find a situation where I need to write duplicate codes in a for loop, where the "init step" to identical to the "update step":

``````// duplicate `next()`
for (let x = next(); p(x); x = next()) {
f(x)
}

// the same in a while loop
let x = next()
while (p(x)) {
f(x)
x = next()
}
``````

It is not much a problem when `next()` is short, but often it's not:

``````// problem is evident when next is long or even inline
let x = mmmmm(rewqreqw(rewqrqew()), rewqrewq(), rewqreqw())
while (p(x)) {
f(x)
x = mmmmm(rewqreqw(rewqrqew()), rewqrewq(), rewqreqw())
}

``````

How can I deal with this situation?

There are multiple common approaches to avoid repeating a complex update-step:

1. Use a lambda:

``````auto g = [&]{ return mmmmm(rewqreqw(rewqrqew()), rewqrewq(), rewqreqw()); };
for (auto x = g(); p(x); x = g(x))
f(x);
``````

``````auto x = dummy;
while (p(x = mmmmm(rewqreqw(rewqrqew()), rewqrewq(), rewqreqw())))
f(x);
``````

A variant using the comma-operator:

``````auto x = dummy;
while (x = mmmmm(rewqreqw(rewqrqew()), rewqrewq(), rewqreqw()), p(x))
f(x);
``````
3. Use an infinite loop with a `break`:

``````for (;;) {
auto x = mmmmm(rewqreqw(rewqrqew()), rewqrewq(), rewqreqw());
if (!p(x)) break;
f(x);
}
``````

Which looks and performs best in your case?
You decide.

• All of them looks equally good for me. Thanks. Sep 27, 2019 at 5:42

I'm not sure what language you're using, but many languages have an abstraction already for calling a function to produce the next element of a sequence, in a more precise way than a for or while loop. It's often called an iterator or a generator.

For example, in Scala, you can write:

``````Iterator.continually(next()).takeWhile(p).map(f)
``````

If your language supports higher-order functions, you can create your own abstraction easily. It's also sometimes implemented in OOP languages by implementing an interface with something like a `getNext` and a `hasNext` function.