## Friday, December 27, 2013

### Fun with Guava: Interleaving Iterables

Problem: given some number (finite, possibly 0) of iterables, create an iterable that interleaves their elements.
For example, given `[1, 2, 3]` and `[x, y, z]`, return `[1, x, 2, y, 3, z]`. Note that the iterables may be of different sizes -- some may be empty or even infinite. When a particular iterable has no more elements, just skip it (i.e. don't pad with nulls for the purpose of interleaving).
```public static <T> FluentIterable<T> interleave(final Iterable<? extends Iterable<? extends T>> iterables) {
return new FluentIterable<T>() {
@Override
public Iterator<T> iterator() {
return new AbstractIterator<T>() {
final Iterator<Iterator<? extends T>> iterators; {
List<Iterator<? extends T>> list = Lists.newLinkedList();
for (Iterable<? extends T> iterable : iterables) {
list.add(iterable.iterator());
}
iterators = Iterators.cycle(list);
}

@Override
protected T computeNext() {
while (iterators.hasNext()) {
Iterator<? extends T> iter = iterators.next();
if (iter.hasNext()) {
return iter.next();
} else {
iterators.remove();
}
}
return endOfData();
}
};
}
};
}
```
And thus:
```System.out.println(
interleave(
ImmutableList.of(
Iterables.cycle("+", "-"),
ImmutableList.of(1, 2, 3, 4),
Collections.emptyList(),
Iterables.cycle(true, false, null)
)
).limit(20)
);
// [+, 1, true, -, 2, false, +, 3, null, -, 4, true, +, false, -, null, +, true, -, false]
```