4

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?

asked Sep 27, 2019 at 1:28
1

2 Answers 2

4

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);
    
  2. Use a dummy initialization and assign in the condition:

    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.

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

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.

answered Sep 27, 2019 at 13:35

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.