1 package com.github.davidmoten.rx.util; 2 3 import java.util.Iterator; 4 5 import rx.Observable; 6 import rx.Observable.Transformer; 7 import rx.functions.Func2; 8 9 import com.github.davidmoten.rx.util.MapWithIndex.Indexed; 10 11 public final class MapWithIndex<T> implements Transformer<T, Indexed<T>> { 12 13 private static class Holder { 14 static final MapWithIndex<?> INSTANCE = new MapWithIndex<Object>(); 15 } 16 17 @SuppressWarnings("unchecked") 18 public static <T> MapWithIndex<T> instance() { 19 return (MapWithIndex<T>) Holder.INSTANCE; 20 } 21 22 @Override 23 public Observable<Indexed<T>> call(Observable<T> source) { 24 25 return source.zipWith(NaturalNumbers.instance(), new Func2<T, Long, Indexed<T>>() { 26 27 @Override 28 public Indexed<T> call(T t, Long n) { 29 return new Indexed<T>(t, n); 30 } 31 }); 32 } 33 34 public static final class Indexed<T> { 35 private final long index; 36 private final T value; 37 38 public Indexed(T value, long index) { 39 this.index = index; 40 this.value = value; 41 } 42 43 @Override 44 public String toString() { 45 return index + "->" + value; 46 } 47 48 public long index() { 49 return index; 50 } 51 52 public T value() { 53 return value; 54 } 55 56 } 57 58 private static final class NaturalNumbers implements Iterable<Long> { 59 60 private static class Holder { 61 static final NaturalNumbers INSTANCE = new NaturalNumbers(); 62 } 63 64 static NaturalNumbers instance() { 65 return Holder.INSTANCE; 66 } 67 68 @Override 69 public Iterator<Long> iterator() { 70 return new Iterator<Long>() { 71 72 private long n = 0; 73 74 @Override 75 public boolean hasNext() { 76 return true; 77 } 78 79 @Override 80 public Long next() { 81 return n++; 82 } 83 84 @Override 85 public void remove() { 86 throw new RuntimeException("not supported"); 87 } 88 }; 89 } 90 91 } 92 93 }