Created
November 6, 2014 03:38
-
-
Save ghadishayban/ed64040c9c7de4b4663c to your computer and use it in GitHub Desktop.
Transducers <3 Iterators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(import clojure.lang.RT) | |
(defn iterator [xfn iter] | |
(XFIterator. xfn (RT/iter iter))) ;; clojure 1.7.0-alpha3 for RT/iter |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import clojure.lang.RT; | |
import clojure.lang.IFn; | |
import clojure.lang.AFn; | |
import java.util.Iterator; | |
import java.util.ArrayList; | |
import java.util.NoSuchElementException; | |
public class XFIterator implements Iterator { | |
static IFn append = new AFn(){ | |
public Object invoke(Object result){ | |
return result; | |
} | |
public Object invoke(Object result, Object input){ | |
XFIterator i = (XFIterator) result; | |
i.buf.add(input); | |
return i; | |
} | |
}; | |
private final IFn xform; | |
private Iterator iter; | |
private final ArrayList buf; | |
private int pos = 0; | |
public XFIterator (IFn xform, Iterator iter) { | |
this.iter = iter; | |
this.buf = new ArrayList(); | |
this.xform = (IFn) xform.invoke(append); | |
} | |
public boolean hasNext() { | |
if (remaining()) | |
return true; | |
pull(); | |
return remaining(); | |
} | |
private boolean remaining() { | |
if (pos < buf.size()) | |
return true; | |
return false; | |
} | |
private Object bufNext() { | |
Object ret = buf.get(pos); | |
pos++; | |
if (pos == buf.size()) { | |
buf.clear(); | |
pos = 0; | |
} | |
return ret; | |
} | |
public Object next() { | |
if (remaining()) { | |
return bufNext(); | |
} | |
pull(); | |
if (remaining()) { | |
return bufNext(); | |
} | |
throw new NoSuchElementException(); | |
} | |
private void pull() { | |
if (iter == null) | |
return; | |
while (buf.size() == 0) { | |
if(iter.hasNext()) { | |
if(RT.isReduced(xform.invoke(this, iter.next()))) { | |
iter = null; | |
xform.invoke(this); | |
return; | |
} | |
} else { | |
iter = null; | |
xform.invoke(this); | |
return; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment