简体   繁体   中英

Is there a possibility to make function working like a for loop?

I was wondering if there is any way to write a custom method working as a "for" loop. Because of very unusual iteration throught objects (well, not as usual as typical iteration) I' am forced to rewrite it every time I want to use it.

Sorry for my English and very unclear explaination, I'm not a very communicative person, but I think that sample below will explain my problem correctly. The code below is not a real code, but just a scheme. Pointers and references can be used wrong but what I mean is to show my conception.

 class Element{
          Element *next;       // Pointer to the next object
          Element *previous;   // Pointer to the previous object
          // There are also some primitives (int, double etc.) there.

          void actionA(int a){ /* sth happpens to the primitives and may affect *next and *previous */ } 
          void actionB(int b,int c){ /* just like above */ }
          // ............. and even more methods 

    }




void makeActionA(int i){
       Element pointer=start.next;
       while(pointer!=end){
            Element tmp=pointer.next;
            pointer.actionA(i);          //X
            pointer=tmp;
        }
    }

void makeActionBC(int i,int j){
       Element pointer=start.next;
       while(pointer!=end){
            Element tmp=pointer.next;
            pointer.actionB(i,j);            //X
            pointer.actionC(i,j,i*j);        //X
            pointer=tmp;
        }
    }
    // AND SO ON

We can see that structers of makeAction methods are nearly the same except the lines marked with "X". I want to make it shorter without stupid repeating like it is in a "for" loop.

   void custom_loop(Element pointer,Element start, Element end){ 
            pointer=start.next;
            while(pointer!=end){
                Element tmp=pointer.next;
                {
                        // Magical function that read the code between the brackets in code.
                }
                pointer=tmp;

            }
    }

And replace makeAction methods with more simple ones using the custom_loop

    void makeActionA(int i){
          Element t,s,e;
          custom_loop(t;s;e){
               t.actionA(i); 
          }
    }

    void makeActionBC(int i,int j){
          Element t,s,e;
          custom_loop(t;s;e){
               t.actionB(i,j);
               t.actionC(i,j,i*j); 
          }
    }

The only solution which comes to my mind are some magical tricks with metaprograming and macros. I'm not really into them, but they won't scare me off. I'm looking forward to the solution. Many thanks. And sorry for my English again.

In c++, you may do

template <typename F>
void makeElementAction(Element& element, F f){
   for (auto* pointer = &element; pointer != nullptr; pointer = pointer->next) {
       f(*pointer);
   }
}

With a call like

makeElementAction(root, [&](Element& element) { element.actionA(i); });

In Java you can implement interface Iterable , which allows you to iterate "iterable" structures using for loop:

Element start = ...;
for (Element current : start) {
   // do something with current element
}

class Element implements Iterable<Element> {
    ...

    public Iterator<Element> iterator() {
        return new ElementIterator(this);
    }
}

class ElementIterator implements Iterator<Element> {
    private Element current;

    ElementIterator(Element start) {
        this.current = start;
    }

    public boolean hasNext() {
        return current != null;
    }

    public Element next() {
        Element result = current;
        current = current.next;
        return result;
    }
}

I've found an interesting structre. It solves the problem also.

Loop looks that:

public static void loop(Element start, Element end, T t){
         for (Element pointer = start; pointer != end; pointer = pointer.next) {
              t.run(pointer);
          }
}
interface T{
    void run(Element pointer);
 }

And new methods look like that

void makeActionA(int i){
     loop(s,e,(pointer)-> pointer.actionA(i) );
 }

void makeActionBC(int i,int j){
     loop(s,e,(pointer)->{pointer.actionB(i,j); pointer.actionC(i,j,i*j);} );
 }

Links: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html : http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM