From c7a398170fe3bc8b0a9c0014d8e8183e392eda83 Mon Sep 17 00:00:00 2001 From: Ben Culkin Date: Mon, 14 Dec 2020 18:24:47 -0500 Subject: Implement NestList NestList is a recursive list structure, inspired by the way lists work in Rakudo (formerly Perl 6). --- src/main/java/bjc/esodata/FlatNestIterator.java | 103 ++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/main/java/bjc/esodata/FlatNestIterator.java (limited to 'src/main/java/bjc/esodata/FlatNestIterator.java') diff --git a/src/main/java/bjc/esodata/FlatNestIterator.java b/src/main/java/bjc/esodata/FlatNestIterator.java new file mode 100644 index 0000000..42981f5 --- /dev/null +++ b/src/main/java/bjc/esodata/FlatNestIterator.java @@ -0,0 +1,103 @@ +package bjc.esodata; + +import java.util.*; + +import bjc.data.*; + +final class FlatNestIterator implements ListIterator +{ + private Deque>>> iterators; + + public FlatNestIterator(ListIterator>> iterator) + { + this.iterators = new ArrayDeque<>(); + this.iterators.add(iterator); + } + + @Override + public boolean hasNext() { + boolean result = false; + do { + result = iterators.peek().hasNext(); + + if (result == false) iterators.pop(); + } while (result == false && iterators.isEmpty() == false); + + return result; + } + + @Override + public Element next() { + Holder element = Holder.of(null); + do { + element = iterators.peek().next().extract((ele) -> { + return Holder.of(ele); + }, (lst) -> { + // Ignore empty sublists. + if (lst.size() != 0) iterators.push(lst.listIterator()); + + return null; + }); + } while (element == null && hasNext()); + + if (element == null) throw new NoSuchElementException(); + + return element.getValue(); + } + + @Override + public boolean hasPrevious() { + boolean result = false; + do { + result = iterators.peek().hasPrevious(); + + if (result == false) iterators.pop(); + } while (result == false && iterators.isEmpty() == false); + + return result; + } + + @Override + public Element previous() { + Holder element = Holder.of(null); + do { + element = iterators.peek().previous().extract((ele) -> { + return Holder.of(ele); + }, (lst) -> { + // Ignore empty sublists. + if (lst.size() != 0) iterators.push(lst.listIterator()); + + return null; + }); + } while (element == null && hasPrevious()); + + if (element == null) throw new NoSuchElementException(); + + return element.getValue(); + } + + @Override + public int nextIndex() { + return iterators.peek().nextIndex(); + } + + @Override + public int previousIndex() { + return iterators.peek().previousIndex(); + } + + @Override + public void remove() { + iterators.peek().remove(); + } + + @Override + public void set(Element e) { + iterators.peek().set(Either.left(e)); + } + + @Override + public void add(Element e) { + iterators.peek().add(Either.left(e)); + } +} \ No newline at end of file -- cgit v1.2.3