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 }